1/*
2 *  tests.c
3 *  xnu_quick_test
4 *
5 *  Created by Jerry Cottingham on 3/25/05.
6 *  Copyright 2008 Apple Inc. All rights reserved.
7 *
8 */
9
10#include "tests.h"
11#include <sys/ipc.h>		/* for message queue tests */
12#include <sys/msg.h>		/* for message queue tests */
13#include <sys/syscall.h>	/* for get / settid */
14#include <sys/sysctl.h>		/* for determining hw */
15#include <sys/kas_info.h>	/* for kas_info() */
16#include <AvailabilityMacros.h>	/* for determination of Mac OS X version (tiger, leopard, etc.) */
17#include <libkern/OSByteOrder.h> /* for OSSwap32() */
18#include <mach/mach.h>
19
20
21extern char		g_target_path[ PATH_MAX ];
22extern int		g_skip_setuid_tests;
23extern int		g_is_single_user;
24
25
26void print_acct_debug_strings( char * my_ac_comm );
27
28
29#if TEST_SYSTEM_CALLS /* system calls to do */
30	"reboot",             /* 55 = reboot */
31	"revoke",             /* 56 = revoke */
32	"sbrk",               /* 69 = sbrk */
33	"sstk",               /* 70 = sstk */
34	"mount",              /* 167 = mount */
35	"unmount",            /* 159 = unmount */
36	"undelete",           /* 205 = undelete */
37	"watchevent",         /* 231 = watchevent */
38	"waitevent",          /* 232 = waitevent */
39	"modwatch",           /* 233 = modwatch */
40	"fsctl",              /* 242 = fsctl */
41	"initgroups",         /* 243 = initgroups */
42	"semsys",             /* 251 = semsys */
43	"semconfig",          /* 257 = semconfig */
44	"msgsys",             /* 252 = msgsys */
45	"shmsys",             /* 253 = shmsys */
46	"load_shared_file",   /* 296 = load_shared_file */
47	"reset_shared_file",  /* 297 = reset_shared_file */
48	"new_system_shared_regions",  /* 298 = new_system_shared_regions */
49	"shared_region_map_file_np",  /* 299 = shared_region_map_file_np */
50	"shared_region_make_private_np",  /* 300 = shared_region_make_private_np */
51	"__pthread_kill",     /* 328 = __pthread_kill */
52	"pthread_sigmask",    /* 329 = pthread_sigmask */
53	"__disable_threadsignal",  /* 331 = __disable_threadsignal */
54	"__pthread_markcancel",  /* 332 = __pthread_markcancel */
55	"__pthread_canceled",  /* 333 = __pthread_canceled */
56	"__semwait_signal",   /* 334 = __semwait_signal */
57	"audit",              /* 350 = audit */
58	"auditon",            /* 351 = auditon */
59	"getaudit",           /* 355 = getaudit */
60	"setaudit",           /* 356 = setaudit */
61	"getaudit_addr",      /* 357 = getaudit_addr */
62	"setaudit_addr",      /* 358 = setaudit_addr */
63	"auditctl",           /* 359 = auditctl */
64#endif
65
66/*  **************************************************************************************************************
67 *	Test the syscall system call.
68 *  **************************************************************************************************************
69 */
70int syscall_test( void * the_argp )
71{
72	int			my_err;
73	int			my_fd = -1;
74	char *			my_pathp;
75	kern_return_t           my_kr;
76
77	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
78        if(my_kr != KERN_SUCCESS){
79                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
80                goto test_failed_exit;
81        }
82
83	*my_pathp = 0x00;
84	strcpy( my_pathp, &g_target_path[0] );
85	strcat( my_pathp, "/" );
86
87	/* create a test file */
88	my_err = create_random_name( my_pathp, 1 );
89	if ( my_err != 0 ) {
90		goto test_failed_exit;
91	}
92
93	/* use an indirect system call to open our test file.
94	 * I picked open since it uses a path pointer which grows to 64 bits in an LP64 environment.
95	 */
96	my_fd = syscall( SYS_open, my_pathp, (O_RDWR | O_EXCL), 0 );
97	if ( my_fd == -1 ) {
98		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
99		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
100		goto test_failed_exit;
101	}
102
103	my_err = 0;
104	goto test_passed_exit;
105
106test_failed_exit:
107	my_err = -1;
108
109test_passed_exit:
110	if ( my_fd != -1 )
111		close( my_fd );
112	if ( my_pathp != NULL ) {
113		remove( my_pathp );
114		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
115	 }
116	return( my_err );
117}
118
119/*  **************************************************************************************************************
120 *	Test fork wait4, and exit system calls.
121 *  **************************************************************************************************************
122 */
123int fork_wait4_exit_test( void * the_argp )
124{
125	int				my_err, my_status;
126    pid_t			my_pid, my_wait_pid;
127	struct rusage	my_usage;
128
129	/* spin off another process */
130	my_pid = fork( );
131	if ( my_pid == -1 ) {
132		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
133		return( -1 );
134	}
135	else if ( my_pid == 0 ) {
136		struct stat		my_sb;
137
138		/* child process does very little then exits */
139		my_err = stat( &g_target_path[0], &my_sb );
140		if ( my_err != 0 ) {
141			printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
142			printf( "\t path we stated \"%s\" \n", &g_target_path[0] );
143			exit( -1 );
144		}
145		exit( 44 );
146	}
147
148	/* parent process waits for child to exit */
149	my_wait_pid = wait4( my_pid, &my_status, 0, &my_usage );
150	if ( my_wait_pid == -1 ) {
151		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
152		return( -1 );
153	}
154
155	/* wait4 should return our child's pid when it exits */
156	if ( my_wait_pid != my_pid ) {
157		printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
158		return( -1 );
159	}
160
161	/* kind of just guessing on these values so if this fails we should take a closer
162	 * look at the returned rusage structure.
163	 */
164	if ( my_usage.ru_utime.tv_sec > 1 || my_usage.ru_stime.tv_sec > 1 ||
165		 my_usage.ru_majflt > 1000 || my_usage.ru_msgsnd > 100 ) {
166		printf( "wait4 returned an odd looking rusage structure \n" );
167		return( -1 );
168	}
169
170	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) == 44 ) {
171	}
172	else {
173		printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
174		return( -1 );
175	}
176
177	return( 0 );
178}
179
180/*  **************************************************************************************************************
181 *	Test fsync, ftruncate, lseek, pread, pwrite, read, readv, truncate, write, writev system calls.
182 *  **************************************************************************************************************
183 */
184int read_write_test( void * the_argp )
185{
186	int			my_fd = -1;
187	int			my_err;
188	char *			my_pathp = NULL;
189	char *			my_bufp = NULL;
190	ssize_t			my_result;
191	off_t			my_current_offset;
192	struct iovec		my_iovs[2];
193	struct stat		my_sb;
194	kern_return_t           my_kr;
195
196        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
197        if(my_kr != KERN_SUCCESS){
198                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
199                goto test_failed_exit;
200        }
201
202        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, MY_BUFFER_SIZE, VM_FLAGS_ANYWHERE);
203        if(my_kr != KERN_SUCCESS){
204                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
205                goto test_failed_exit;
206        }
207
208	*my_pathp = 0x00;
209	strcat( my_pathp, &g_target_path[0] );
210	strcat( my_pathp, "/" );
211
212	/* create a test file */
213	my_err = create_random_name( my_pathp, 1 );
214	if ( my_err != 0 ) {
215		goto test_failed_exit;
216	}
217
218	my_fd = open( my_pathp, O_RDONLY, 0 );
219	if ( my_fd == -1 ) {
220		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
221		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
222		goto test_failed_exit;
223	}
224
225	/* should get EOF since the file is empty at this point */
226	my_result = read( my_fd, my_bufp, 10);
227	if ( my_result == -1 ) {
228		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
229		goto test_failed_exit;
230	}
231	if ( my_result != 0 ) {
232		if ( sizeof( ssize_t ) > sizeof( int ) ) {
233			printf( "read call failed - should have read 0 bytes on empty file - read %ld \n", (long int) my_result );
234		}
235		else {
236			printf( "read call failed - should have read 0 bytes on empty file - read %d \n", (int) my_result );
237		}
238		goto test_failed_exit;
239	}
240
241	/* this write should fail since we opened for read only */
242	my_result = write( my_fd, my_bufp, 10 );
243	my_err = errno;
244	if ( my_result != -1 ) {
245		if ( sizeof( ssize_t ) > sizeof( int ) ) {
246			printf( "write should have failed for read only fd -  %ld \n", (long int) my_result );
247		}
248		else {
249			printf( "write should have failed for read only fd -  %d \n", (int) my_result );
250		}
251		goto test_failed_exit;
252	}
253	if ( my_err != EBADF ) {
254		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
255		printf( "should have failed with EBADF error %d \n", EBADF );
256		goto test_failed_exit;
257	}
258
259	/* now really write some data */
260	close( my_fd );
261	my_fd = open( my_pathp, O_RDWR, 0 );
262	if ( my_fd == -1 ) {
263		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
264		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
265		goto test_failed_exit;
266	}
267
268	memset( my_bufp, 'j', MY_BUFFER_SIZE );
269	my_result = write( my_fd, my_bufp, MY_BUFFER_SIZE );
270	if ( my_result == -1 ) {
271		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
272		goto test_failed_exit;
273	}
274	if ( my_result != MY_BUFFER_SIZE ) {
275		printf( "write failed to write out all the data \n" );
276		goto test_failed_exit;
277	}
278
279	/* push data to disk */
280	my_err = fsync( my_fd );
281	if ( my_err == -1 ) {
282		printf( "fsync failed with errno %d - %s \n", errno, strerror( errno ) );
283		goto test_failed_exit;
284	}
285
286	/* now verify the write worked OK using readv */
287	lseek( my_fd, 0, SEEK_SET );
288	bzero( (void *)my_bufp, MY_BUFFER_SIZE );
289	my_iovs[0].iov_base = my_bufp;
290	my_iovs[0].iov_len = 16;
291	my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 16) ;
292	my_iovs[1].iov_len = 16;
293
294	my_result = readv( my_fd, &my_iovs[0], 2 );
295	if ( my_result == -1 ) {
296		printf( "readv call failed with error %d - \"%s\" \n", errno, strerror( errno) );
297		goto test_failed_exit;
298	}
299	if ( my_result != 32 ) {
300		printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result );
301		goto test_failed_exit;
302	}
303	if ( *my_bufp != 'j' || *(my_bufp + (MY_BUFFER_SIZE - 1)) != 'j' ) {
304		printf( "readv failed to get correct data \n" );
305		goto test_failed_exit;
306	}
307
308	/* test ftruncate */
309	my_err = ftruncate( my_fd, 0 );
310	if ( my_err == -1 ) {
311		printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
312		goto test_failed_exit;
313	}
314
315	my_err = fstat( my_fd, &my_sb );
316	if ( my_err == -1 ) {
317		printf( "fstat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
318		goto test_failed_exit;
319	}
320	if ( my_sb.st_size != 0 ) {
321		printf( "ftruncate call failed - file size is wrong \n" );
322		goto test_failed_exit;
323	}
324
325	/* test writev */
326	lseek( my_fd, 0, SEEK_SET );
327	memset( my_bufp, 'z', MY_BUFFER_SIZE );
328	my_iovs[0].iov_base = my_bufp;
329	my_iovs[0].iov_len = 8;
330	my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 8) ;
331	my_iovs[1].iov_len = 8;
332	my_result = writev( my_fd, &my_iovs[0], 2 );
333	if ( my_result == -1 ) {
334		printf( "writev call failed with error %d - \"%s\" \n", errno, strerror( errno) );
335		goto test_failed_exit;
336	}
337	if ( my_result != 16 ) {
338		printf( "writev failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result );
339		goto test_failed_exit;
340	}
341
342	/* now verify the writev worked OK */
343	lseek( my_fd, 0, SEEK_SET );
344	bzero( (void *)my_bufp, MY_BUFFER_SIZE );
345	my_iovs[0].iov_base = my_bufp;
346	my_iovs[0].iov_len = 8;
347	my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 8) ;
348	my_iovs[1].iov_len = 8;
349
350	my_result = readv( my_fd, &my_iovs[0], 2 );
351	if ( my_result == -1 ) {
352		printf( "readv call failed with error %d - \"%s\" \n", errno, strerror( errno) );
353		goto test_failed_exit;
354	}
355	if ( my_result != 16 ) {
356		printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result );
357		goto test_failed_exit;
358	}
359	if ( *my_bufp != 'z' || *(my_bufp + (MY_BUFFER_SIZE - 1)) != 'z' ) {
360		printf( "readv failed to get correct data \n" );
361		goto test_failed_exit;
362	}
363
364	/* test pread and pwrite */
365	my_current_offset = lseek( my_fd, 0, SEEK_CUR );
366	if ( my_current_offset == -1 ) {
367		printf( "lseek call failed with error %d - \"%s\" \n", errno, strerror( errno) );
368		goto test_failed_exit;
369	}
370
371	my_result =  pwrite( my_fd, "jer", 3, my_current_offset );
372	if ( my_result == -1 ) {
373		printf( "pwrite call failed with error %d - \"%s\" \n", errno, strerror( errno) );
374		goto test_failed_exit;
375	}
376	if ( my_result != 3 ) {
377		printf( "pwrite failed to write all the data \n" );
378		goto test_failed_exit;
379	}
380
381	/* make sure file position did not advance */
382	if ( my_current_offset != lseek( my_fd, 0, SEEK_CUR ) ) {
383		printf( "pwrite advanced file positiion \n" );
384		goto test_failed_exit;
385	}
386
387	bzero( (void *)my_bufp, MY_BUFFER_SIZE );
388	my_result =  pread( my_fd, my_bufp, 3, my_current_offset );
389	if ( my_result == -1 ) {
390		printf( "pread call failed with error %d - \"%s\" \n", errno, strerror( errno) );
391		goto test_failed_exit;
392	}
393	if ( my_result != 3 ) {
394		printf( "pread failed to write all the data \n" );
395		goto test_failed_exit;
396	}
397
398	/* make sure file position did not advance */
399	if ( my_current_offset != lseek( my_fd, 0, SEEK_CUR ) ) {
400		printf( "pread advanced file positiion \n" );
401		goto test_failed_exit;
402	}
403
404	/* make sure pread and pwrite transferred correct data */
405	if ( strcmp( my_bufp, "jer" ) != 0 ) {
406		printf( "pread or pwrite failed to read / write correct data \n" );
407		goto test_failed_exit;
408	}
409
410	/* test truncate */
411	my_err = truncate( my_pathp, 0 );
412	if ( my_err == -1 ) {
413		printf( "truncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
414		goto test_failed_exit;
415	}
416
417	my_err = stat( my_pathp, &my_sb );
418	if ( my_err == -1 ) {
419		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
420		goto test_failed_exit;
421	}
422	if ( my_sb.st_size != 0 ) {
423		printf( "truncate call failed - file size is wrong \n" );
424		goto test_failed_exit;
425	}
426
427	my_err = 0;
428	goto test_passed_exit;
429
430test_failed_exit:
431	my_err = -1;
432
433test_passed_exit:
434	if ( my_fd != -1 )
435		close( my_fd );
436	if ( my_pathp != NULL ) {
437		remove( my_pathp );
438		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
439	 }
440	if ( my_bufp != NULL )
441		vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, MY_BUFFER_SIZE);
442	return( my_err );
443}
444
445/*  **************************************************************************************************************
446 *	Test close, fpathconf, fstat, open, pathconf system calls.
447 *  **************************************************************************************************************
448 */
449int open_close_test( void * the_argp )
450{
451	int		my_err;
452	int		my_fd = -1;
453	char *		my_pathp = NULL;
454	ssize_t		my_result;
455	long		my_pconf_result;
456	struct stat	my_sb;
457	char		my_buffer[32];
458	kern_return_t           my_kr;
459
460        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
461        if(my_kr != KERN_SUCCESS){
462                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
463                goto test_failed_exit;
464        }
465
466	*my_pathp = 0x00;
467	strcat( my_pathp, &g_target_path[0] );
468	strcat( my_pathp, "/" );
469
470	/* create a test file */
471	my_err = create_random_name( my_pathp, 1 );
472	if ( my_err != 0 ) {
473		goto test_failed_exit;
474	}
475
476	/*  test O_WRONLY case */
477	my_fd = open( my_pathp, O_WRONLY, 0 );
478	if ( my_fd == -1 ) {
479		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
480		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
481		goto test_failed_exit;
482	}
483
484	/* test pathconf and fpathconf */
485	my_pconf_result = pathconf( my_pathp, _PC_PATH_MAX );
486	if ( my_pconf_result == -1 ) {
487		printf( "pathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
488		goto test_failed_exit;
489	}
490//	printf( "_PC_PATH_MAX %ld \n", my_pconf_result );
491	/* results look OK? */
492	if ( my_pconf_result < PATH_MAX ) {
493		printf( "pathconf - _PC_PATH_MAX - looks like wrong results \n" );
494		goto test_failed_exit;
495	}
496
497	my_pconf_result = fpathconf( my_fd, _PC_NAME_MAX );
498	if ( my_pconf_result == -1 ) {
499		printf( "fpathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
500		goto test_failed_exit;
501	}
502//	printf( "_PC_NAME_MAX %ld \n", my_pconf_result );
503	/* results look OK? */
504	if ( my_pconf_result < 6 ) {
505		printf( "fpathconf - _PC_NAME_MAX - looks like wrong results \n" );
506		goto test_failed_exit;
507	}
508
509	/* write some data then try to read it */
510	my_result = write( my_fd, "kat", 3 );
511	my_err = errno;
512	if ( my_result != 3 ) {
513		if ( sizeof( ssize_t ) > sizeof( int ) ) {
514			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
515		}
516		else {
517			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
518		}
519		goto test_failed_exit;
520	}
521
522	/* Try to read - this should fail since we opened file with O_WRONLY */
523	my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
524	my_err = errno;
525	if ( my_result != -1 ) {
526		printf( "read call should have failed with errno 9 (EBADF) \n" );
527		goto test_failed_exit;
528	}
529	else if ( my_err != EBADF ) {
530		printf( "read call should have failed with errno 9 (EBADF).  actually failed with %d - \"%s\" \n", my_err, strerror( my_err) );
531		goto test_failed_exit;
532	}
533
534	close( my_fd );
535
536	/*  test O_TRUNC and O_APPEND case */
537	my_fd = open( my_pathp, (O_RDWR | O_TRUNC | O_APPEND), 0 );
538	if ( my_fd == -1 ) {
539		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
540		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
541		goto test_failed_exit;
542	}
543
544	my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
545	if ( my_result == -1 ) {
546		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
547		goto test_failed_exit;
548	}
549	if ( my_result != 0 ) {
550		printf( "read failed - should have read 0 bytes. \n" );
551		goto test_failed_exit;
552	}
553
554	my_result = write( my_fd, "kat", 3 );
555	my_err = errno;
556	if ( my_result != 3 ) {
557		if ( sizeof( ssize_t ) > sizeof( int ) ) {
558			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
559		}
560		else {
561			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
562		}
563		goto test_failed_exit;
564	}
565
566	/* add some more data to the test file - this should be appended */
567	lseek( my_fd, 0, SEEK_SET );
568	my_result = write( my_fd, "zzz", 3 );
569	my_err = errno;
570	if ( my_result != 3 ) {
571		if ( sizeof( ssize_t ) > sizeof( int ) ) {
572			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
573		}
574		else {
575			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
576		}
577		goto test_failed_exit;
578	}
579
580	/* now verify the writes */
581	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
582	lseek( my_fd, 0, SEEK_SET );
583	my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
584	if ( my_result == -1 ) {
585		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
586		goto test_failed_exit;
587	}
588	if ( my_buffer[0] != 'k' || my_buffer[5] != 'z' ) {
589		printf( "read failed to get correct data \n" );
590		goto test_failed_exit;
591	}
592
593	/* test fstat */
594	my_err = fstat( my_fd, &my_sb );
595	if ( my_err == -1 ) {
596		printf( "fstat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
597		goto test_failed_exit;
598	}
599	if ( my_sb.st_size != 6 ) {
600		printf( "fstat call failed - st_size is wrong \n" );
601		goto test_failed_exit;
602	}
603	if ( !S_ISREG( my_sb.st_mode ) ) {
604		printf( "fstat call failed - st_mode does not indicate regular file \n" );
605		goto test_failed_exit;
606	}
607
608	my_err = 0;
609	goto test_passed_exit;
610
611test_failed_exit:
612	my_err = -1;
613
614test_passed_exit:
615	if ( my_fd != -1 )
616		close( my_fd );
617	if ( my_pathp != NULL ) {
618		remove( my_pathp );
619		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
620	 }
621	return( my_err );
622}
623
624/*  **************************************************************************************************************
625 *	Test link, stat and unlink system calls.
626 *  **************************************************************************************************************
627 */
628int link_stat_unlink_test( void * the_argp )
629{
630	int			my_err;
631	int			my_fd = -1;
632	char *			my_pathp = NULL;
633	char *			my_path2p = NULL;
634	nlink_t			my_link_count;
635	ssize_t			my_result;
636	struct stat		my_sb;
637	kern_return_t           my_kr;
638
639        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
640        if(my_kr != KERN_SUCCESS){
641                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
642                goto test_failed_exit;
643        }
644
645        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_path2p, PATH_MAX, VM_FLAGS_ANYWHERE);
646        if(my_kr != KERN_SUCCESS){
647                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
648                goto test_failed_exit;
649        }
650
651	*my_pathp = 0x00;
652	*my_path2p = 0x00;
653	strcat( my_pathp, &g_target_path[0] );
654	strcat( my_pathp, "/" );
655
656	/* create a test file */
657	my_err = create_random_name( my_pathp, 1 );
658	if ( my_err != 0 ) {
659		goto test_failed_exit;
660	}
661
662	/* now create a name for the link file */
663	strcat( my_path2p, my_pathp );
664	strcat( my_path2p, "link" );
665
666	/* get the current link count */
667	my_err = stat( my_pathp, &my_sb );
668	if ( my_err != 0 ) {
669		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
670		goto test_failed_exit;
671	}
672	my_link_count = my_sb.st_nlink;
673
674	/* check file size (should be 0) */
675	if ( my_sb.st_size != 0 ) {
676		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
677		printf( "st_size is not 0 \n" );
678		goto test_failed_exit;
679	}
680
681	/* change file size */
682	my_fd = open( my_pathp, O_RDWR, 0 );
683	if ( my_fd == -1 ) {
684		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
685		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
686		goto test_failed_exit;
687	}
688	my_result = write( my_fd, "kat", 3 );
689	my_err = errno;
690	if ( my_result != 3 ) {
691		if ( sizeof( ssize_t ) > sizeof( int ) ) {
692			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
693		}
694		else {
695			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
696		}
697		goto test_failed_exit;
698	}
699	close( my_fd );
700	my_fd = -1;
701
702	/* now link another file to our test file and recheck link count */
703	my_err = link( my_pathp, my_path2p );
704	if ( my_err != 0 ) {
705		printf( "link call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
706		goto test_failed_exit;
707	}
708	my_err = stat( my_pathp, &my_sb );
709	if ( my_err != 0 ) {
710		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
711		goto test_failed_exit;
712	}
713	if ( (my_link_count + 1) != my_sb.st_nlink ) {
714		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
715		printf( "incorrect st_nlink \n" );
716		goto test_failed_exit;
717	}
718
719	/* check file size (should be 3) */
720	if ( my_sb.st_size != 3 ) {
721		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
722		printf( "st_size is not 3 \n" );
723		goto test_failed_exit;
724	}
725
726	/* now make sure unlink works OK */
727	my_err = unlink( my_path2p );
728	if ( my_err != 0 ) {
729		printf( "unlink call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
730		goto test_failed_exit;
731	}
732	my_err = stat( my_pathp, &my_sb );
733	if ( my_err != 0 ) {
734		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
735		goto test_failed_exit;
736	}
737	if ( my_link_count != my_sb.st_nlink ) {
738		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
739		printf( "incorrect st_nlink \n" );
740		goto test_failed_exit;
741	}
742
743	my_err = 0;
744	goto test_passed_exit;
745
746test_failed_exit:
747	my_err = -1;
748
749test_passed_exit:
750	if ( my_fd != -1 )
751		close( my_fd );
752	if ( my_pathp != NULL ) {
753		remove( my_pathp );
754		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
755	}
756	if ( my_path2p != NULL ) {
757		remove( my_path2p );
758		vm_deallocate(mach_task_self(), (vm_address_t)my_path2p, PATH_MAX);
759	}
760	return( my_err );
761}
762
763/*  **************************************************************************************************************
764 *	Test chdir and fchdir system calls.
765 *  **************************************************************************************************************
766 */
767int chdir_fchdir_test( void * the_argp )
768{
769	int			my_err;
770	int			my_fd = -1;
771	char *			my_pathp = NULL;
772	char *			my_file_namep;
773	struct stat		my_sb;
774	struct stat		my_sb2;
775	kern_return_t           my_kr;
776
777	char *cwd = getwd(NULL);	/* Save current working directory so we can restore later */
778
779        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
780        if(my_kr != KERN_SUCCESS){
781                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
782                goto test_failed_exit;
783        }
784
785	*my_pathp = 0x00;
786	strcat( my_pathp, &g_target_path[0] );
787	strcat( my_pathp, "/" );
788
789	/* create a test file */
790	my_err = create_random_name( my_pathp, 1 );
791	if ( my_err != 0 ) {
792		goto test_failed_exit;
793	}
794
795	/* test by doing a stat on the test file using a full path and a partial path.
796	 * get full path first.
797	 */
798	my_err = stat( my_pathp, &my_sb );
799	if ( my_err != 0 ) {
800		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
801		goto test_failed_exit;
802	}
803
804	/* now do the chdir to our test directory and then do the stat relative to that location */
805	my_err = chdir( &g_target_path[0] );
806	if ( my_err != 0 ) {
807		printf( "chdir call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
808		goto test_failed_exit;
809	}
810
811	my_file_namep = strrchr( my_pathp, '/' );
812	my_file_namep++;
813	my_err = stat( my_file_namep, &my_sb2 );
814	if ( my_err != 0 ) {
815		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
816		goto test_failed_exit;
817	}
818
819	/* both stat buffers should contain the same data since they should be referencing the same
820	 * file.
821	 */
822	if ( my_sb.st_ino != my_sb2.st_ino || my_sb.st_size != my_sb2.st_size ||
823		 my_sb.st_mtimespec.tv_sec != my_sb2.st_mtimespec.tv_sec ||
824		 my_sb.st_mtimespec.tv_nsec != my_sb2.st_mtimespec.tv_nsec  ) {
825		printf( "chdir call appears to have failed.  stat buffer contents do not match! \n" );
826		goto test_failed_exit;
827	}
828
829	/* now change our current directory to "/" and use fchdir to get back to our test directory */
830	my_err = chdir( "/" );
831	if ( my_err != 0 ) {
832		printf( "chdir call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
833		goto test_failed_exit;
834	}
835
836	/* we should not find our test file at the root of the volume */
837	my_err = stat( my_file_namep, &my_sb2 );
838	if ( my_err == 0 ) {
839		printf( "chdir to root volume has failed \n" );
840		goto test_failed_exit;
841	}
842
843	/* get a file descriptor to the test directory for use with fchdir */
844	my_fd = open( &g_target_path[0], O_RDONLY, 0 );
845	if ( my_fd == -1 ) {
846		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
847		printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
848		goto test_failed_exit;
849	}
850
851	my_err = fchdir( my_fd );
852	if ( my_err == -1 ) {
853		printf( "fchdir call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
854		goto test_failed_exit;
855	}
856
857	my_err = stat( my_file_namep, &my_sb2 );
858	if ( my_err != 0 ) {
859		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
860		goto test_failed_exit;
861	}
862
863	/* both stat buffers should contain the same data since they should be referencing the same
864	 * file.
865	 */
866	if ( my_sb.st_ino != my_sb2.st_ino || my_sb.st_size != my_sb2.st_size ||
867		 my_sb.st_mtimespec.tv_sec != my_sb2.st_mtimespec.tv_sec ||
868		 my_sb.st_mtimespec.tv_nsec != my_sb2.st_mtimespec.tv_nsec  ) {
869		printf( "chdir call appears to have failed.  stat buffer contents do not match! \n" );
870		goto test_failed_exit;
871	}
872
873	my_err = 0;
874	goto test_passed_exit;
875
876test_failed_exit:
877	my_err = -1;
878
879test_passed_exit:
880	if ( my_fd != -1 )
881		close( my_fd );
882	if ( my_pathp != NULL ) {
883		remove( my_pathp );
884		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
885	 }
886	if ( chdir(cwd) != 0)	/* Changes back to original directory, don't screw up the env. */
887		my_err = -1;
888	return( my_err );
889}
890
891/*  **************************************************************************************************************
892 *	Test access, chmod and fchmod system calls.
893 *  **************************************************************************************************************
894 */
895int access_chmod_fchmod_test( void * the_argp )
896{
897	int		error_occurred;
898	int		my_err;
899	int		my_fd = -1;
900
901	char *		my_pathp = NULL;
902
903	uid_t		euid,ruid;
904	struct stat	my_sb;
905
906	FILE *		file_handle;
907
908	kern_return_t	my_kr;
909
910
911        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
912        if(my_kr != KERN_SUCCESS){
913                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
914                goto test_failed_exit;
915        }
916
917	*my_pathp = 0x00;
918	strcat( my_pathp, &g_target_path[0] );
919	strcat( my_pathp, "/" );
920
921	/* create a test file */
922	my_err = create_random_name( my_pathp, 1 );
923	if ( my_err != 0 ) {
924		goto test_failed_exit;
925	}
926
927
928	/* test chmod */
929	my_err = chmod( my_pathp, S_IRWXU );
930	if ( my_err == -1 ) {
931		printf( "chmod call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
932		goto test_failed_exit;
933	}
934
935	my_err = chmod( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) );
936	if ( my_err == -1 ) {
937		printf( "chmod call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
938		goto test_failed_exit;
939	}
940
941	/* test access - this should fail */
942	my_err = access( my_pathp, (X_OK) );
943	if ( my_err == 0 ) {
944		printf( "access call should have failed, but did not. \n" );
945		goto test_failed_exit;
946	}
947	else if ( my_err == -1  ) {
948		int tmp = 0;
949		tmp = getuid( );
950
951		/* special case when running as root - we get back EPERM when running as root */
952		my_err = errno;
953		if ( ( tmp == 0 && my_err != EPERM) || (tmp != 0 && my_err != EACCES) ) {
954			printf( "access failed with errno %d - %s. \n", my_err, strerror( my_err ) );
955			goto test_failed_exit;
956		}
957	}
958
959	/* verify correct modes are set */
960	my_err = stat( my_pathp, &my_sb );
961	if ( my_err != 0 ) {
962		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
963		goto test_failed_exit;
964	}
965
966	if ( (my_sb.st_mode & (S_IRWXO | S_IXGRP)) != 0 ||
967		 (my_sb.st_mode & (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == 0 ) {
968		printf( "chmod call appears to have failed.  stat shows incorrect values in st_mode! \n" );
969		goto test_failed_exit;
970	}
971
972
973	/*  another test for the access system call  -- refer ro radar# 6725311 */
974
975
976	/*
977	 * This test makes sure that the access system call does not give the current user extra
978	 * permissions on files the current user does not own. From radar #6725311, this could
979	 * happen when the current user calls access() on a file owned by the current user in
980	 * the same directory as the other files not owned by the current user.
981	 *
982	 * Note: This test expects that the effective uid (euid) is set to root.
983	 *
984	 */
985
986	/* Create a file that root owns  */
987	file_handle = fopen(FILE_NOTME, "w");
988	fclose(file_handle);
989
990	/* Currently running as root (through setreuid manipulation), switch to running as the current user. */
991	euid = geteuid();
992	ruid = getuid();
993	setreuid(ruid, ruid);
994
995	/* Create a file that the current user owns  */
996	file_handle = fopen(FILE_ME, "w");
997	fclose(file_handle);
998
999	error_occurred = 0;
1000
1001	/* Try to remove the file owned by root (this should fail). */
1002	my_err = unlink(FILE_NOTME);
1003
1004	if (my_err < 0) {
1005		my_err = errno;
1006	}
1007
1008	if (my_err == 0) {
1009		printf("Unresolved: First attempt deleted '" FILE_NOTME "'! \n");
1010		error_occurred = 1;
1011	} else {
1012		printf("Status: First attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
1013
1014		/* Set _DELETE_OK on a file that the current user owns */
1015		access(FILE_ME, _DELETE_OK);
1016
1017		/* Try to remove the file owned by root again (should give us: EPERM [13]) */
1018		my_err = unlink(FILE_NOTME);
1019
1020		if (my_err < 0) {
1021		    my_err = errno;
1022		}
1023
1024		if (my_err == 0) {
1025			printf("Failed: Second attempt deleted '" FILE_NOTME "'!\n");
1026			error_occurred = 1;
1027		} else if (my_err == 13) {
1028			printf("Passed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
1029		} else {
1030			printf("Failed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
1031			error_occurred = 1;
1032		}
1033	}
1034
1035	/* Reset to running as root */
1036	setreuid(ruid, euid);
1037
1038	if(error_occurred == 1) {
1039		goto test_failed_exit;
1040	}
1041
1042
1043	/* end of test*/
1044
1045
1046	/* test fchmod */
1047	my_fd = open( my_pathp, O_RDONLY, 0 );
1048	if ( my_fd == -1 ) {
1049		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1050		printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
1051		goto test_failed_exit;
1052	}
1053
1054	my_err = fchmod( my_fd, S_IRWXU );
1055	if ( my_err == -1 ) {
1056		printf( "fchmod call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1057		goto test_failed_exit;
1058	}
1059
1060	my_err = stat( my_pathp, &my_sb );
1061	if ( my_err != 0 ) {
1062		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1063		goto test_failed_exit;
1064	}
1065
1066	/* verify correct modes are set */
1067	if ( (my_sb.st_mode & (S_IRWXG | S_IRWXO)) != 0 ||
1068		 (my_sb.st_mode & (S_IRWXU)) == 0 ) {
1069		printf( "fchmod call appears to have failed.  stat shows incorrect values in st_mode! \n" );
1070		goto test_failed_exit;
1071	}
1072
1073	my_err = 0;
1074	goto test_passed_exit;
1075
1076test_failed_exit:
1077	my_err = -1;
1078
1079test_passed_exit:
1080	if ( my_fd != -1 )
1081		close( my_fd );
1082	if ( my_pathp != NULL ) {
1083		remove( my_pathp );
1084		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1085	 }
1086	return( my_err );
1087}
1088
1089static bool _prime_groups(void)
1090{
1091	/*
1092	 * prime groups with a known list to ensure consistent test behavior
1093	 */
1094
1095	gid_t	my_exp_groups[] = { getegid(), 20, 61, 12 };
1096	int		my_err;
1097
1098	my_err = setgroups( ( sizeof(my_exp_groups) / sizeof(*my_exp_groups) ), &my_exp_groups[0] );
1099	if ( my_err == -1 ) {
1100		printf( "initial setgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1101		return false;
1102	}
1103
1104	return true;
1105}
1106
1107/*  **************************************************************************************************************
1108 *	Test chown, fchown, lchown, lstat, readlink, symlink system calls.
1109 *  **************************************************************************************************************
1110 */
1111int chown_fchown_lchown_lstat_symlink_test( void * the_argp )
1112{
1113	int			my_err, my_group_count, i;
1114	int			my_fd = -1;
1115	char *			my_pathp = NULL;
1116	char *			my_link_pathp = NULL;
1117	uid_t			my_orig_uid;
1118	gid_t			my_orig_gid, my_new_gid1 = 0, my_new_gid2 = 0;
1119	ssize_t			my_result;
1120	struct stat		my_sb;
1121	gid_t			my_groups[ NGROUPS_MAX ];
1122	char			my_buffer[ 64 ];
1123	kern_return_t           my_kr;
1124
1125        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1126        if(my_kr != KERN_SUCCESS){
1127                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1128                goto test_failed_exit;
1129        }
1130
1131	*my_pathp = 0x00;
1132	strcat( my_pathp, &g_target_path[0] );
1133	strcat( my_pathp, "/" );
1134
1135	/* create a test file */
1136	my_err = create_random_name( my_pathp, 1 );
1137	if ( my_err != 0 ) {
1138		goto test_failed_exit;
1139	}
1140
1141        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_link_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1142        if(my_kr != KERN_SUCCESS){
1143                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1144                goto test_failed_exit;
1145        }
1146
1147	*my_link_pathp = 0x00;
1148	strcat( my_link_pathp, &g_target_path[0] );
1149	strcat( my_link_pathp, "/" );
1150
1151	/* get a test file name for the link */
1152	my_err = create_random_name( my_link_pathp, 0 );
1153	if ( my_err != 0 ) {
1154		goto test_failed_exit;
1155	}
1156
1157	if ( !_prime_groups() ) {
1158		goto test_failed_exit;
1159	}
1160
1161	/* set up by getting a list of groups */
1162	my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
1163
1164	if ( my_group_count == -1 || my_group_count < 1 ) {
1165		printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1166		goto test_failed_exit;
1167	}
1168
1169	my_err = stat( my_pathp, &my_sb );
1170	if ( my_err != 0 ) {
1171		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1172		goto test_failed_exit;
1173	}
1174
1175	/* now change group owner to something other than current value */
1176	my_orig_gid = my_sb.st_gid;
1177	my_orig_uid = my_sb.st_uid;
1178
1179	for ( i = 0; i < my_group_count; i++ ) {
1180		if ( my_orig_gid != my_groups[ i ] ) {
1181			if ( my_new_gid1 == 0 ) {
1182				my_new_gid1 = my_groups[ i ];
1183			}
1184			else if( my_new_gid1 != my_groups[ i ] ) {
1185				my_new_gid2 = my_groups[ i ];
1186				break;
1187			}
1188		}
1189	}
1190	if ( i >= my_group_count ) {
1191		printf( "not enough groups to choose from.  st_gid is the same as current groups! \n" );
1192		goto test_failed_exit;
1193	}
1194
1195	my_err = chown( my_pathp, my_orig_uid, my_new_gid1 );
1196	if ( my_err != 0 ) {
1197		printf( "chown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1198		goto test_failed_exit;
1199	}
1200
1201	/* make sure the group owner was changed */
1202	my_err = stat( my_pathp, &my_sb );
1203	if ( my_err != 0 ) {
1204		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1205		goto test_failed_exit;
1206	}
1207	if ( my_sb.st_gid == my_orig_gid ) {
1208		printf( "chown call failed.  st_gid is not correct! \n" );
1209		goto test_failed_exit;
1210	}
1211
1212	/* change group owner back using fchown */
1213	my_fd = open( my_pathp, O_RDWR, 0 );
1214	if ( my_fd == -1 ) {
1215		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1216		printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
1217		goto test_failed_exit;
1218	}
1219
1220	my_err = fchown( my_fd, my_orig_uid, my_new_gid2 );
1221	if ( my_err != 0 ) {
1222		printf( "fchown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1223		goto test_failed_exit;
1224	}
1225
1226	/* make sure the group owner was changed back to the original value */
1227	my_err = stat( my_pathp, &my_sb );
1228	if ( my_err != 0 ) {
1229		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1230		goto test_failed_exit;
1231	}
1232	if ( my_sb.st_gid == my_new_gid1 ) {
1233		printf( "fchown call failed.  st_gid is not correct! \n" );
1234		goto test_failed_exit;
1235	}
1236
1237	/* create a link file and test lchown */
1238	my_err = symlink( my_pathp, my_link_pathp );
1239	if ( my_err != 0 ) {
1240		printf( "symlink call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1241		goto test_failed_exit;
1242	}
1243
1244	my_err = lstat( my_link_pathp, &my_sb );
1245	if ( my_err != 0 ) {
1246		printf( "lstat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1247		goto test_failed_exit;
1248	}
1249
1250	/* now change group owner to something other than current value */
1251	my_orig_gid = my_sb.st_gid;
1252	my_orig_uid = my_sb.st_uid;
1253	my_err = lchown( my_link_pathp, my_orig_uid, my_new_gid1 );
1254	if ( my_err != 0 ) {
1255		printf( "lchown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1256		goto test_failed_exit;
1257	}
1258
1259	/* make sure the group owner was changed to new value */
1260	my_err = lstat( my_link_pathp, &my_sb );
1261	if ( my_err != 0 ) {
1262		printf( "lstat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1263		goto test_failed_exit;
1264	}
1265	if ( my_sb.st_gid == my_new_gid2 ) {
1266		printf( "lchown call failed.  st_gid is not correct! \n" );
1267		goto test_failed_exit;
1268	}
1269
1270	/* make sure we can read the symlink file */
1271	my_result = readlink( my_link_pathp, &my_buffer[0], sizeof(my_buffer) );
1272	if ( my_result == -1 ) {
1273		printf( "readlink call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1274		goto test_failed_exit;
1275	}
1276	/* make sure we read some data */
1277	if ( my_result < 1 ) {
1278		printf( "readlink failed to read any data. \n" );
1279		goto test_failed_exit;
1280	}
1281
1282	my_err = 0;
1283	goto test_passed_exit;
1284
1285test_failed_exit:
1286	my_err = -1;
1287
1288test_passed_exit:
1289	if ( my_fd != -1 )
1290		close( my_fd );
1291	if ( my_pathp != NULL ) {
1292		remove( my_pathp );
1293		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1294	 }
1295	if ( my_link_pathp != NULL ) {
1296		unlink( my_link_pathp );
1297		vm_deallocate(mach_task_self(), (vm_address_t)my_link_pathp, PATH_MAX);
1298	 }
1299	return( my_err );
1300}
1301
1302/*  **************************************************************************************************************
1303 *	Test fstatfs, getattrlist, getfsstat, statfs, getfsstat64, statfs64, fstatfs64 system calls.
1304 *  **************************************************************************************************************
1305 */
1306
1307#pragma pack(4)
1308struct vol_attr_buf {
1309	u_int32_t	length;
1310	off_t   	volume_size;
1311	u_int32_t	io_blksize;
1312};
1313#pragma pack()
1314typedef struct vol_attr_buf vol_attr_buf;
1315
1316#define STATFS_TEST_PATH	"/tmp"
1317
1318int fs_stat_tests( void * the_argp )
1319{
1320	int			my_err, my_count, i;
1321	int			my_buffer_size, my_buffer64_size;
1322	int			my_fd = -1;
1323	int			is_ufs = 0;
1324	long		my_io_size;
1325	fsid_t		my_fsid;
1326	struct attrlist 	my_attrlist;
1327	vol_attr_buf        my_attr_buf;
1328	void *				my_bufferp = NULL;
1329	struct statfs *		my_statfsp;
1330	kern_return_t       my_kr;
1331
1332	void * my_buffer64p = NULL;
1333	struct statfs64 *	my_statfs64p;
1334
1335	my_buffer64_size = (sizeof(struct statfs64) * 10);
1336
1337	my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_buffer64p, my_buffer64_size, VM_FLAGS_ANYWHERE);
1338	if(my_kr != KERN_SUCCESS){
1339	  printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1340	  goto test_failed_exit;
1341	}
1342
1343	my_buffer_size = (sizeof(struct statfs) * 10);
1344
1345	my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_bufferp, my_buffer_size, VM_FLAGS_ANYWHERE);
1346        if(my_kr != KERN_SUCCESS){
1347                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1348                goto test_failed_exit;
1349        }
1350
1351	my_statfsp = (struct statfs *) my_bufferp;
1352	my_err = statfs( STATFS_TEST_PATH, my_statfsp );
1353	if ( my_err == -1 ) {
1354		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1355		goto test_failed_exit;
1356	}
1357	if ( memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ) {
1358		is_ufs = 1;
1359	}
1360
1361	my_count = getfsstat( (struct statfs *)my_bufferp, my_buffer_size, MNT_NOWAIT );
1362	if ( my_count == -1 ) {
1363		printf( "getfsstat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1364		goto test_failed_exit;
1365	}
1366
1367	/* validate results */
1368	my_statfsp = (struct statfs *) my_bufferp;
1369	for ( i = 0; i < my_count; i++, my_statfsp++ ) {
1370		if ( memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
1371			 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ||
1372			 memcmp( &my_statfsp->f_fstypename[0], "devfs", 5 ) == 0 ||
1373			 memcmp( &my_statfsp->f_fstypename[0], "volfs", 5 ) == 0 ) {
1374			/* found a valid entry */
1375			break;
1376		}
1377	}
1378	if ( i >= my_count ) {
1379		printf( "getfsstat call failed.  could not find valid f_fstypename! \n" );
1380		goto test_failed_exit;
1381	}
1382
1383	/* now try statfs64 */
1384	my_statfs64p = (struct statfs64 *) my_buffer64p;
1385	my_err = statfs64( STATFS_TEST_PATH, my_statfs64p );
1386	if ( my_err == -1 ) {
1387		printf( "statfs64 call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1388		goto test_failed_exit;
1389	}
1390	if ( my_statfs64p->f_fsid.val[0] != my_statfsp->f_fsid.val[0] ||
1391		 my_statfs64p->f_fsid.val[1] != my_statfsp->f_fsid.val[1] ) {
1392		printf( "statfs64 call failed.  wrong f_fsid! \n" );
1393		goto test_failed_exit;
1394	}
1395
1396	my_count = getfsstat64( (struct statfs64 *)my_buffer64p, my_buffer64_size, MNT_NOWAIT );
1397	if ( my_count == -1 ) {
1398		printf( "getfsstat64 call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1399		goto test_failed_exit;
1400	}
1401
1402	/* validate results */
1403	my_statfs64p = (struct statfs64 *) my_buffer64p;
1404	for ( i = 0; i < my_count; i++, my_statfs64p++ ) {
1405		if ( memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 ||
1406			 memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0 ||
1407			 memcmp( &my_statfs64p->f_fstypename[0], "devfs", 5 ) == 0 ||
1408			 memcmp( &my_statfs64p->f_fstypename[0], "volfs", 5 ) == 0 ) {
1409			/* found a valid entry */
1410			break;
1411		}
1412	}
1413	if ( i >= my_count ) {
1414		printf( "getfsstat64 call failed.  could not find valid f_fstypename! \n" );
1415		goto test_failed_exit;
1416	}
1417
1418	/* set up to validate results via multiple sources.  we use getattrlist to get volume
1419	 * related attributes to verify against results from fstatfs and statfs - but only if
1420	 * we are not targeting ufs volume since it doesn't support getattr calls
1421	 */
1422	if ( is_ufs == 0 ) {
1423		memset( &my_attrlist, 0, sizeof(my_attrlist) );
1424		my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
1425		my_attrlist.volattr = (ATTR_VOL_SIZE | ATTR_VOL_IOBLOCKSIZE);
1426		my_err = getattrlist( "/", &my_attrlist, &my_attr_buf, sizeof(my_attr_buf), 0 );
1427		if ( my_err != 0 ) {
1428			printf( "getattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1429			goto test_failed_exit;
1430		}
1431	}
1432
1433	/* open to use as test file for fstatfs */
1434 	my_fd = open( STATFS_TEST_PATH, O_RDONLY, 0 );
1435	if ( my_fd == -1 ) {
1436		printf( "open call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1437		goto test_failed_exit;
1438	}
1439
1440	/* testing fstatfs64 */
1441	my_statfs64p = (struct statfs64 *) my_buffer64p;
1442	my_err = fstatfs64( my_fd, my_statfs64p );
1443	if ( my_err == -1 ) {
1444		printf( "fstatfs64 call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1445		goto test_failed_exit;
1446	}
1447
1448	/* validate results - assumes we only boot from hfs or ufs */
1449	if ( !(memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 ||
1450		   memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0) ) {
1451		printf( "fstatfs64 call failed.  could not find valid f_fstypename! \n" );
1452		goto test_failed_exit;
1453	}
1454
1455	/* testing fstatfs */
1456	my_statfsp = (struct statfs *) my_bufferp;
1457	my_err = fstatfs( my_fd, my_statfsp );
1458	if ( my_err == -1 ) {
1459		printf( "fstatfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1460		goto test_failed_exit;
1461	}
1462
1463	/* validate results */
1464	if ( !(memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
1465		   memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0) ) {
1466		printf( "fstatfs call failed.  could not find valid f_fstypename! \n" );
1467		goto test_failed_exit;
1468	}
1469	my_io_size = my_statfsp->f_iosize;
1470	my_fsid = my_statfsp->f_fsid;
1471	if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
1472		printf( "fstatfs and getattrlist results do not match for volume block size  \n" );
1473		goto test_failed_exit;
1474	}
1475
1476	/* try again with statfs */
1477	my_err = statfs( STATFS_TEST_PATH , my_statfsp );
1478	if ( my_err == -1 ) {
1479		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1480		goto test_failed_exit;
1481	}
1482
1483	/* validate results */
1484	if ( my_io_size != my_statfsp->f_iosize || my_fsid.val[0] != my_statfsp->f_fsid.val[0] ||
1485		 my_fsid.val[1] != my_statfsp->f_fsid.val[1] ) {
1486		printf( "statfs call failed.  wrong f_iosize or f_fsid! \n" );
1487		goto test_failed_exit;
1488	}
1489	if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
1490		printf( "statfs and getattrlist results do not match for volume block size  \n" );
1491		goto test_failed_exit;
1492	}
1493
1494	my_err = 0;
1495	goto test_passed_exit;
1496
1497test_failed_exit:
1498	my_err = -1;
1499
1500test_passed_exit:
1501	if ( my_fd != -1 )
1502		close( my_fd );
1503	if ( my_bufferp != NULL ) {
1504		vm_deallocate(mach_task_self(), (vm_address_t)my_bufferp, my_buffer_size);
1505	 }
1506	 if ( my_buffer64p != NULL ) {
1507		vm_deallocate(mach_task_self(), (vm_address_t)my_buffer64p, my_buffer64_size);
1508	 }
1509
1510	return( my_err );
1511}
1512
1513/*  **************************************************************************************************************
1514 *	Test getpid, getppid, and pipe system calls.
1515 *  **************************************************************************************************************
1516 */
1517int getpid_getppid_pipe_test( void * the_argp )
1518{
1519	int			my_err, my_status;
1520	pid_t		my_pid, my_wait_pid;
1521	ssize_t		my_count;
1522	int			my_fildes[2] = {-1, -1};
1523	off_t		my_current_offset;
1524	char		my_pid_string[64];
1525
1526	my_err = pipe( &my_fildes[0] );
1527	if ( my_err != 0 ) {
1528		printf( "pipe call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1529		goto test_failed_exit;
1530	}
1531
1532	/* make sure we can't seek on a pipe */
1533	my_current_offset = lseek( my_fildes[0], 0, SEEK_CUR );
1534	if ( my_current_offset != -1 ) {
1535		printf( "lseek on pipe should fail but did not \n" );
1536		goto test_failed_exit;
1537	}
1538
1539	/* fork here and use pipe to communicate */
1540	my_pid = fork( );
1541	if ( my_pid == -1 ) {
1542		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
1543		goto test_failed_exit;
1544	}
1545	else if ( my_pid == 0 ) {
1546		/* child process */
1547		unsigned long	my_ppid;
1548		char			my_buffer[64];
1549
1550		close( my_fildes[1] ); /* close write end of pipe */
1551		my_fildes[1] = -1;
1552
1553		/* get the parent's pid using getppid and from the parent (using getpid in porent) */
1554		my_count = read( my_fildes[0], &my_buffer[0], sizeof(my_buffer) );
1555		if ( my_count == -1 ) {
1556			printf( "read from pipe failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1557			exit(-1);
1558		}
1559
1560		/* parent wrote (to our pipe) its pid as character string */
1561		my_ppid = strtoul( &my_buffer[0], NULL, 10 );
1562		if ( my_ppid == 0 ) {
1563			printf( "strtoul failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1564			exit(-1);
1565		}
1566
1567		if ( getppid( ) != my_ppid ) {
1568			printf( "getppid failed.  pid we got from parent does not match getppid result. \n" );
1569			exit(-1);
1570		}
1571		exit(0);
1572	}
1573
1574	/* parent process - get our pid using getpid and send it to child for verification */
1575	close( my_fildes[0] ); /* close read end of pipe */
1576	my_fildes[0] = -1;
1577
1578	sprintf( &my_pid_string[0], "%d\n", getpid( ) );
1579
1580	my_count = write( my_fildes[1], &my_pid_string[0], sizeof(my_pid_string) );
1581	if ( my_count == -1 ) {
1582		printf( "write to pipe failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1583		goto test_failed_exit;
1584	}
1585
1586	/* wait for child to exit */
1587	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
1588	if ( my_wait_pid == -1 ) {
1589		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
1590		goto test_failed_exit;
1591	}
1592
1593	/* wait4 should return our child's pid when it exits */
1594	if ( my_wait_pid != my_pid ) {
1595		printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
1596		goto test_failed_exit;
1597	}
1598
1599	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
1600		printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
1601		goto test_failed_exit;
1602	}
1603
1604	my_err = 0;
1605	goto test_passed_exit;
1606
1607test_failed_exit:
1608	my_err = -1;
1609
1610test_passed_exit:
1611	if ( my_fildes[0] != -1 )
1612		close( my_fildes[0] );
1613	if ( my_fildes[1] != -1 )
1614		close( my_fildes[1] );
1615	return( my_err );
1616}
1617
1618
1619/*  **************************************************************************************************************
1620 *	Test getauid, gettid, getuid, geteuid, issetugid, setaudit_addr, seteuid, settid, settid_with_pid, setuid system calls.
1621 *  **************************************************************************************************************
1622 */
1623int uid_tests( void * the_argp )
1624{
1625	int			my_err, my_status;
1626	pid_t		my_pid, my_wait_pid;
1627
1628	if ( g_skip_setuid_tests != 0 ) {
1629		printf("\t skipping this test \n");
1630		my_err = 0;
1631		goto test_passed_exit;
1632	}
1633
1634	/* test issetugid - should return 1 when not root and 0 when root
1635	 * Figuring out setugid will not work in single-user mode; skip
1636	 * this test in that case.
1637	 */
1638	if (!g_is_single_user) {
1639		my_err = issetugid( );
1640		if ( getuid( ) == 0 ) {
1641			if ( my_err == 1 ) {
1642				printf( "issetugid should return false \n" );
1643				goto test_failed_exit;
1644			}
1645		}
1646		else {
1647			if ( my_err == 0 ) {
1648				printf( "issetugid should return true \n" );
1649				goto test_failed_exit;
1650			}
1651		}
1652	}
1653
1654	/*
1655	 * fork here and do the setuid work in the child
1656	 */
1657	my_pid = fork( );
1658	if ( my_pid == -1 ) {
1659		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
1660		goto test_failed_exit;
1661	}
1662	else if ( my_pid == 0 ) {
1663		/*
1664		 * child process
1665		 */
1666		uid_t			my_ruid, my_euid;
1667		uid_t			my_uid, my_temp_uid;
1668		gid_t			my_gid, my_temp_gid;
1669		auditinfo_addr_t	my_aia;
1670
1671		my_ruid = getuid( );
1672		my_euid = geteuid( );
1673		if ( my_ruid == my_euid ) {
1674			exit( 0 );
1675		}
1676
1677		/* Test getauid, gettid, setaudit_addr, settid, settid_with_pid */
1678		/* get our current uid and gid for comparison later */
1679		my_uid = getuid( );
1680		my_gid = getgid( );
1681
1682		my_err = syscall( SYS_settid, 4444, 5555 );
1683		//my_err = settid( 4444, 5555 );
1684		if (my_err != 0) {
1685			printf( "settid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1686			exit( -1 );
1687		}
1688
1689		my_err = syscall( SYS_gettid, &my_temp_uid, &my_temp_gid );
1690		//my_err = gettid( &my_temp_uid, &my_temp_gid );
1691		if (my_err != 0) {
1692			printf( "gettid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1693			exit( -1 );
1694		}
1695		if (my_temp_uid != 4444) {
1696			printf("get / settid test failed - wrong uid was set - %d \n", my_temp_uid);
1697			exit( -1 );
1698		}
1699		if (my_temp_gid != 5555) {
1700			printf("get / settid test failed - wrong gid was set - %d \n", my_temp_gid);
1701			exit( -1 );
1702		}
1703
1704		/* resume original identity */
1705		my_err = syscall( SYS_settid, KAUTH_UID_NONE, KAUTH_GID_NONE );
1706		//my_err = settid( KAUTH_UID_NONE, KAUTH_GID_NONE );
1707		if (my_err != 0) {
1708			printf( "settid revert - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1709			exit( -1 );
1710		}
1711
1712		/* values should be returned to original settings */
1713		my_temp_uid = getuid( );
1714		if (my_temp_uid == 4444) {
1715			printf("test failed - wrong uid was set - %d \n", my_temp_uid);
1716			exit( -1 );
1717		}
1718		my_temp_gid = getgid( );
1719		if (my_temp_gid == 5555) {
1720			printf("test failed - wrong gid was set - %d \n", my_temp_gid);
1721			exit( -1 );
1722		}
1723
1724		/*
1725		 * Assume the identity of our parent.
1726		 */
1727		my_err = syscall( SYS_settid_with_pid, getppid( ), 1 );
1728		//my_err = settid_with_pid, my_target_pid, 1 );
1729		if (my_err != 0) {
1730			printf( "settid_with_pid assume - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1731			exit( -1 );
1732		}
1733
1734		/*
1735		 * Resume our identity.
1736		 */
1737		my_err = syscall( SYS_settid_with_pid, 0, 0 );
1738		//my_err = settid_with_pid( my_target_pid, 0 );
1739		if (my_err != 0) {
1740			printf( "settid_with_pid resume - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1741			exit( -1 );
1742		}
1743
1744		/*
1745		 * test to make sure setaudit_addr doesn't cause audit info to get lost from
1746		 * the credential.
1747		 */
1748		bzero( &my_aia, sizeof(my_aia) );
1749		my_aia.ai_auid = 442344;
1750		my_aia.ai_asid = AU_ASSIGN_ASID;
1751		my_aia.ai_termid.at_type = AU_IPv4;
1752		my_err = setaudit_addr( &my_aia, sizeof(my_aia) );
1753		if (my_err != 0) {
1754			printf( "setaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1755			exit( -1 );
1756		}
1757
1758		my_aia.ai_auid = 0;
1759		my_err = getaudit_addr( &my_aia, sizeof(my_aia) );
1760		if (my_err != 0) {
1761			printf( "getaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1762			exit( -1 );
1763		}
1764		//printf("new audit ID is %d \n", my_aia.ai_auid);
1765
1766		if (my_aia.ai_auid != 442344) {
1767			printf("test failed - wrong audit ID was set - %d \n", my_aia.ai_auid);
1768			exit( -1 );
1769		}
1770
1771		/* change real uid and effective uid to current euid */
1772		my_err = setuid( my_euid );
1773		if ( my_err == -1 ) {
1774			printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1775			exit( -1 );
1776		}
1777		if ( getuid( ) != my_euid ) {
1778			printf( "setuid call failed to set the real uid \n" );
1779			exit( -1 );
1780		}
1781
1782		/* change effective uid to current euid - really a NOP */
1783		my_err = seteuid( my_euid );
1784		if ( my_err == -1 ) {
1785			printf( "seteuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1786			exit( -1 );
1787		}
1788		if ( geteuid( ) != my_euid ) {
1789			printf( "seteuid call failed to set the original euid \n" );
1790			exit( -1 );
1791		}
1792
1793		/* change real uid and effective uid to original real uid */
1794		my_err = setuid( my_ruid );
1795		if ( my_err == -1 ) {
1796			printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1797			exit( -1 );
1798		}
1799		if ( getuid( ) != my_ruid ) {
1800			printf( "setuid call failed to set the real uid \n" );
1801			exit( -1 );
1802		}
1803
1804		exit(0);
1805	}
1806
1807	/*
1808	 * parent process -
1809	 * wait for child to exit
1810	 */
1811	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
1812	if ( my_wait_pid == -1 ) {
1813		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
1814		goto test_failed_exit;
1815	}
1816
1817	/* wait4 should return our child's pid when it exits */
1818	if ( my_wait_pid != my_pid ) {
1819		printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
1820		goto test_failed_exit;
1821	}
1822
1823	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
1824		printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
1825		goto test_failed_exit;
1826	}
1827
1828	my_err = 0;
1829	goto test_passed_exit;
1830
1831test_failed_exit:
1832	my_err = -1;
1833
1834test_passed_exit:
1835	return( my_err );
1836}
1837
1838/*  **************************************************************************************************************
1839 *	Test mknod, sync system calls.
1840 *  **************************************************************************************************************
1841 */
1842int mknod_sync_test( void * the_argp )
1843{
1844	int			my_err;
1845	char *	my_pathp =      NULL;
1846	kern_return_t           my_kr;
1847
1848	if ( g_skip_setuid_tests != 0 ) {
1849		printf("\t skipping this test \n");
1850		my_err = 0;
1851		goto test_passed_exit;
1852	}
1853
1854        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1855        if(my_kr != KERN_SUCCESS){
1856                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1857                goto test_failed_exit;
1858        }
1859
1860	*my_pathp = 0x00;
1861	strcat( my_pathp, "/dev/" );
1862
1863	/* get a unique name for our test file */
1864	my_err = create_random_name( my_pathp, 0 );
1865	if ( my_err != 0 ) {
1866		goto test_failed_exit;
1867	}
1868
1869	my_err = mknod( my_pathp, (S_IFCHR | S_IRWXU), 0 );
1870	if ( my_err == -1 ) {
1871		printf( "mknod failed with errno %d - %s \n", errno, strerror( errno ) );
1872		printf( "path \"%s\" \n", my_pathp );
1873		goto test_failed_exit;
1874	}
1875
1876	/* not really sure what to do with sync call test */
1877	sync( );
1878	my_err = 0;
1879	goto test_passed_exit;
1880
1881test_failed_exit:
1882	my_err = -1;
1883
1884test_passed_exit:
1885	if ( my_pathp != NULL ) {
1886		remove( my_pathp );
1887		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1888	 }
1889	return( my_err );
1890}
1891
1892/*  **************************************************************************************************************
1893 *	Test chflags, fchflags system calls.
1894 *  **************************************************************************************************************
1895 */
1896int chflags_fchflags_test( void * the_argp )
1897{
1898	int				my_err;
1899	int				my_fd = -1;
1900	u_int			my_flags;
1901	char *			my_pathp = NULL;
1902	struct stat		my_sb;
1903	kern_return_t           my_kr;
1904
1905        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1906        if(my_kr != KERN_SUCCESS){
1907                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1908                goto test_failed_exit;
1909        }
1910
1911	*my_pathp = 0x00;
1912	strcat( my_pathp, &g_target_path[0] );
1913	strcat( my_pathp, "/" );
1914
1915	/* create a test file */
1916	my_err = create_random_name( my_pathp, 1 );
1917	if ( my_err != 0 ) {
1918		goto test_failed_exit;
1919	}
1920
1921	/* make test file unchangable */
1922	my_err = stat( my_pathp, &my_sb );
1923	if ( my_err != 0 ) {
1924		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1925		goto test_failed_exit;
1926	}
1927
1928	my_flags = (my_sb.st_flags | UF_IMMUTABLE);
1929	my_err = chflags( my_pathp, my_flags );
1930	if ( my_err != 0 ) {
1931		printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1932		goto test_failed_exit;
1933	}
1934
1935	/* should fail with EPERM since we cannot change the file now */
1936	my_fd = open( my_pathp, O_RDWR, 0 );
1937	if ( my_fd == -1 && errno != EPERM ) {
1938		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1939		printf( "open failed with wrong error - should be EPERM \n" );
1940		goto test_failed_exit;
1941	}
1942
1943	/* this open should work OK */
1944	my_fd = open( my_pathp, O_RDONLY, 0 );
1945	if ( my_fd == -1 ) {
1946		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1947		goto test_failed_exit;
1948	}
1949
1950	my_err = stat( my_pathp, &my_sb );
1951	if ( my_err != 0 ) {
1952		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1953		goto test_failed_exit;
1954	}
1955
1956	my_flags = (my_sb.st_flags & ~UF_IMMUTABLE);
1957	my_err = fchflags( my_fd, my_flags );
1958	if ( my_err != 0 ) {
1959		printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1960		goto test_failed_exit;
1961	}
1962
1963	close( my_fd );
1964	my_fd = -1;
1965
1966	/* should now work */
1967	my_fd = open( my_pathp, O_RDWR, 0 );
1968	if ( my_fd == -1 ) {
1969		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1970		goto test_failed_exit;
1971	}
1972
1973	my_err = 0;
1974	goto test_passed_exit;
1975
1976test_failed_exit:
1977	my_err = -1;
1978
1979test_passed_exit:
1980	if ( my_fd != -1 )
1981		close( my_fd );
1982	if ( my_pathp != NULL ) {
1983		remove( my_pathp );
1984		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1985	 }
1986	return( my_err );
1987}
1988
1989
1990/*  **************************************************************************************************************
1991 *	Test kill, vfork, execve system calls.
1992 *  **************************************************************************************************************
1993 */
1994/*  There are many new exec() situations to test now that 64-bit is in. These extra tests are in response to
1995 * rdar://4606399 and rdar://4607285. It should cover every permutation of the following variables.
1996 *
1997 *  - Current Process "Bitness": 			64 or 32
1998 *  - exec()'ed process "bitness": 			64 or 32
1999 *  	(if 64 bit, size of page zero:)			(4GB or 4KB)
2000 *  - Parent Process "Bitness":				64 or 32
2001
2002 *  Test to make sure certain inheritance properties of fork()'ed children
2003 * are correctly set.
2004 *  1. 64 bit process forking() 64-bit child, child execing() 64-bit file (4GB pagezero)
2005 *  2. 64 bit process forking() 64-bit child, child execing() 64-bit file (4KB pagezero)
2006 *  3. 64 bit process forking() 64-bit child, child execing() 32-bit file
2007 *  4. 32 bit process forking() 32-bit child, child execing() 32-bit file
2008 *  5. 32 bit process forking() 32-bit child, child execing() 64 bit file (4GB pagezero)
2009 *  6. 32 bit process forking() 32-bit child, child execing() 64 bit file (4KB pagezero)
2010 *
2011 */
2012
2013
2014int execve_kill_vfork_test( void * the_argp )
2015{
2016	int	my_err, my_status;
2017	pid_t	my_pid, my_wait_pid;
2018	char *	errmsg = NULL;
2019	char * argvs[2] = {"", NULL};
2020	int bits = get_bits();		/* Gets actual processor bit-ness. */
2021
2022	if (bits != 32 && bits != 64) {
2023		printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits());
2024		return(-1);
2025	}
2026
2027	if (get_architecture() == -1) {
2028		errmsg = "get_architecture() could not determine the CPU architecture.\n";
2029		goto test_failed_exit;
2030	}
2031
2032	if (get_architecture() == INTEL) {
2033		struct stat sb;
2034
2035		if (bits == 64 && sizeof(long) == 8) {
2036			/*
2037			 * Running on x86_64 hardware and running in 64-bit mode.
2038			 * Check cases 1, 2, 3 and fork a child to check 4, 5, 6.
2039			 */
2040			errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4G pagezero.\n";
2041			argvs[0] = "sleep-x86_64-4G";
2042			if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 1))		goto test_failed_exit;
2043
2044			errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4K Pagezero.\n";
2045			argvs[0] = "sleep-x86_64-4K";
2046			if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 1))		goto test_failed_exit;
2047
2048			errmsg = "execve failed: from x64_64 forking and exec()ing 32-bit i386 process.\n";
2049			argvs[0] = "sleep-i386";
2050			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1))		goto test_failed_exit;
2051
2052			/* Fork off a helper process and load a 32-bit program in it to test 32->64 bit exec(). */
2053			errmsg = "execve failed to exec the helper process.\n";
2054			argvs[0] = "launch-i386";
2055			if (do_execve_test("helpers/launch-i386", argvs, NULL, 1) != 0)		goto test_failed_exit;
2056
2057			/* Test posix_spawn for i386, x86_64 (should succeed) */
2058			errmsg = NULL;
2059			if (do_spawn_test(CPU_TYPE_I386, 0))
2060				goto test_failed_exit;
2061			if (do_spawn_test(CPU_TYPE_X86_64, 0))
2062				goto test_failed_exit;
2063		}
2064		else if (bits == 64 && sizeof(long) == 4) {
2065			/*
2066			 * Running on x86_64 hardware, but actually running in 32-bit mode.
2067			 * Check cases 4, 5, 6 and fork a child to check 1, 2, 3.
2068			 */
2069			errmsg = "execve failed: from i386 forking and exec()ing i386 process.\n";
2070			argvs[0] = "sleep-i386";
2071			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 0))		goto test_failed_exit;
2072
2073			errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4G pagezero.\n";
2074			argvs[0] = "sleep-x86_64-4G";
2075			if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 0))		goto test_failed_exit;
2076
2077			errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4K pagezero.\n";
2078			argvs[0] = "sleep-x86_64-4K";
2079			if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 0))		goto test_failed_exit;
2080
2081			/* Fork off a helper process and load a 64-bit program in it to test 64->32 bit exec(). */
2082			errmsg = "execve failed to exec the helper process.\n";
2083			argvs[0] = "launch-x86_64";
2084			if (do_execve_test("helpers/launch-x86_64", argvs, NULL, 1) != 0)	goto test_failed_exit;
2085
2086			/* Test posix_spawn for i386, x86_64 (should succeed) */
2087			errmsg = NULL;
2088			if (do_spawn_test(CPU_TYPE_I386, 0))
2089				goto test_failed_exit;
2090			if (do_spawn_test(CPU_TYPE_X86_64, 0))
2091				goto test_failed_exit;
2092		}
2093		else if (bits == 32) {
2094			/* Running on i386 hardware. Check cases 4. */
2095			errmsg = "execve failed: from i386 forking and exec()ing 32-bit i386 process.\n";
2096			argvs[0] = "sleep-i386";
2097			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) 		goto test_failed_exit;
2098
2099			/* Test posix_spawn for x86_64 (should fail), i386 (should succeed) */
2100			errmsg = NULL;
2101			if (do_spawn_test(CPU_TYPE_X86_64, 1))
2102				goto test_failed_exit;
2103			if (do_spawn_test(CPU_TYPE_I386, 0))
2104				goto test_failed_exit;
2105		}
2106	} else if(get_architecture() == ARM) {
2107
2108#ifdef CPU_TYPE_ARM64
2109		if (bits == 64) {
2110			/* Running on arm64 hardware. */
2111			errmsg = "execve failed: from arm64 forking and exec()ing 64-bit arm process.\n";
2112			argvs[0] = "sleep-arm";
2113			if (do_execve_test("helpers/sleep-arm64", argvs, NULL, 1))
2114				goto test_failed_exit;
2115
2116			/* Test posix_spawn for arm64 (should succeed) */
2117			errmsg = NULL;
2118			if (do_spawn_test(CPU_TYPE_ARM64, 0))
2119				goto test_failed_exit;
2120		}
2121#endif
2122
2123		/* Exec arm test on both arm and arm64 */
2124		errmsg = "execve failed: from arm forking and exec()ing 32-bit arm process.\n";
2125		argvs[0] = "sleep-arm";
2126		if (do_execve_test("helpers/sleep-arm", argvs, NULL, 1))
2127			goto test_failed_exit;
2128
2129		/* Test posix_spawn for arm (should succeed) */
2130		errmsg = NULL;
2131		if (do_spawn_test(CPU_TYPE_ARM, 0))
2132			goto test_failed_exit;
2133
2134	}
2135	else {
2136		/* Just in case someone decides we need more architectures in the future */
2137		printf("get_architecture() returned unknown architecture");
2138		return(-1);
2139	}
2140
2141	return 0;
2142
2143test_failed_exit:
2144	if (errmsg)
2145		printf("%s", errmsg);
2146	return -1;
2147}
2148
2149
2150/*  **************************************************************************************************************
2151 *	Test getegid, getgid, getgroups, setegid, setgid, setgroups system calls.
2152 *  **************************************************************************************************************
2153 */
2154int groups_test( void * the_argp )
2155{
2156	int			my_err, i;
2157	int			my_group_count, my_orig_group_count;
2158	gid_t		my_real_gid;
2159	gid_t		my_effective_gid;
2160	gid_t		my_removed_gid;
2161	gid_t		my_new_gid;
2162	gid_t		my_groups[ NGROUPS_MAX ];
2163
2164	if ( g_skip_setuid_tests != 0 ) {
2165		printf("\t skipping this test \n");
2166		my_err = 0;
2167		goto test_passed_exit;
2168	}
2169
2170	my_real_gid = getgid( );
2171	my_effective_gid = getegid( );
2172
2173	if ( !_prime_groups() ) {
2174		goto test_failed_exit;
2175	}
2176
2177	/* start by getting list of groups the current user belongs to */
2178	my_orig_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
2179
2180	if ( my_orig_group_count == -1 || my_orig_group_count < 1 ) {
2181		printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2182		goto test_failed_exit;
2183	}
2184
2185	/* make sure real and effective gids are correct */
2186	for ( i = 0; i < my_orig_group_count; i++ ) {
2187		if ( my_groups[i] == my_real_gid )
2188			break;
2189	}
2190	if ( i >= my_orig_group_count ) {
2191		printf( "getgid or getgroups call failed.  could not find real gid in list of groups. \n" );
2192		goto test_failed_exit;
2193	}
2194	for ( i = 0; i < my_orig_group_count; i++ ) {
2195		if ( my_groups[i] == my_effective_gid )
2196			break;
2197	}
2198	if ( i >= my_orig_group_count ) {
2199		printf( "getegid or getgroups call failed.  could not find effective gid in list of groups. \n" );
2200		goto test_failed_exit;
2201	}
2202
2203	/* remove the last group */
2204	my_removed_gid = my_groups[ (my_orig_group_count - 1) ];
2205	my_err = setgroups( (my_orig_group_count - 1), &my_groups[0] );
2206	if ( my_err == -1 ) {
2207		printf( "setgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2208		goto test_failed_exit;
2209	}
2210
2211	my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
2212
2213	if ( my_group_count == -1 || my_group_count < 1 ) {
2214		printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2215		goto test_failed_exit;
2216	}
2217
2218	/* make sure setgroups dropped one */
2219	if ( my_orig_group_count <= my_group_count ) {
2220		printf( "setgroups call failed.  current group count is too high. \n" );
2221		goto test_failed_exit;
2222	}
2223
2224	/* now put removed gid back */
2225	my_groups[ (my_orig_group_count - 1) ] = my_removed_gid;
2226	my_err = setgroups( my_orig_group_count, &my_groups[0] );
2227	if ( my_err == -1 ) {
2228		printf( "setgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2229		goto test_failed_exit;
2230	}
2231
2232	/* find a group to change real and effective gid to then do it */
2233	my_new_gid = -1;
2234	for ( i = 0; i < my_orig_group_count; i++ ) {
2235		if ( my_groups[i] == my_effective_gid || my_groups[i] == my_real_gid )
2236			continue;
2237		my_new_gid = my_groups[i];
2238	}
2239
2240	if ( my_new_gid == -1 ) {
2241		printf( "could not find a gid to switch to. \n" );
2242		goto test_failed_exit;
2243	}
2244
2245	/* test setegid */
2246	my_err = setegid( my_new_gid );
2247	if ( my_err == -1 ) {
2248		printf( "setegid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2249		goto test_failed_exit;
2250	}
2251	/* verify it changed */
2252	if ( getegid( ) != my_new_gid ) {
2253		printf( "setegid failed to change the effective gid. \n" );
2254		goto test_failed_exit;
2255	}
2256	/* change it back to original value */
2257	my_err = setegid( my_effective_gid );
2258	if ( my_err == -1 ) {
2259		printf( "setegid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2260		goto test_failed_exit;
2261	}
2262
2263	/* test setgid */
2264	my_err = setgid( my_new_gid );
2265	if ( my_err == -1 ) {
2266		printf( "setgid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2267		goto test_failed_exit;
2268	}
2269	/* verify it changed */
2270	if ( getgid( ) != my_new_gid ) {
2271		printf( "setgid failed to change the real gid. \n" );
2272		goto test_failed_exit;
2273	}
2274	/* change it back to original value */
2275	my_err = setgid( my_real_gid );
2276	if ( my_err == -1 ) {
2277		printf( "setegid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2278		goto test_failed_exit;
2279	}
2280
2281	my_err = 0;
2282	goto test_passed_exit;
2283
2284test_failed_exit:
2285	my_err = -1;
2286
2287test_passed_exit:
2288	return( my_err );
2289}
2290
2291
2292/*  **************************************************************************************************************
2293 *	Test dup, dup2, getdtablesize system calls.
2294 *  **************************************************************************************************************
2295 */
2296int dup_test( void * the_argp )
2297{
2298	int			my_err;
2299	int			my_fd = -1;
2300	int			my_newfd = -1;
2301	int			my_table_size, my_loop_counter = 0;
2302	char *		my_pathp = NULL;
2303	ssize_t		my_count;
2304	char		my_buffer[64];
2305	kern_return_t           my_kr;
2306
2307        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2308        if(my_kr != KERN_SUCCESS){
2309                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2310                goto test_failed_exit;
2311        }
2312
2313	*my_pathp = 0x00;
2314	strcat( my_pathp, &g_target_path[0] );
2315	strcat( my_pathp, "/" );
2316
2317	/* create a test file */
2318	my_err = create_random_name( my_pathp, 1 );
2319	if ( my_err != 0 ) {
2320		goto test_failed_exit;
2321	}
2322
2323	/* test dup, dup2, getdtablesize */
2324	my_table_size = getdtablesize( );
2325	if ( my_table_size < 20 ) {
2326		printf( "getdtablesize should return at least 20, returned %d \n", my_table_size );
2327		goto test_failed_exit;
2328	}
2329
2330	my_fd = open( my_pathp, O_RDWR, 0 );
2331	if ( my_fd == -1 ) {
2332		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2333		goto test_failed_exit;
2334	}
2335
2336	my_newfd = dup( my_fd );
2337	if ( my_newfd == -1 ) {
2338		printf( "dup call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2339		goto test_failed_exit;
2340	}
2341
2342redo:
2343	/* now write somne data to the orginal and new fd */
2344	/* make sure test file is empty */
2345	my_err = ftruncate( my_fd, 0 );
2346	if ( my_err == -1 ) {
2347		printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2348		goto test_failed_exit;
2349	}
2350
2351	lseek( my_fd, 0, SEEK_SET );
2352	my_count = write( my_fd, "aa", 2 );
2353	if ( my_count == -1 ) {
2354		printf( "write call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2355		goto test_failed_exit;
2356	}
2357
2358	my_count = write( my_newfd, "xx", 2 );
2359	if ( my_count == -1 ) {
2360		printf( "write call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2361		goto test_failed_exit;
2362	}
2363
2364	/* now read it back and make sure data is correct */
2365	lseek( my_fd, 0, SEEK_SET );
2366	my_count = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
2367	if ( my_count == -1 ) {
2368		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2369		goto test_failed_exit;
2370	}
2371	if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) {
2372		printf( "wrong data in test file. \n" );
2373		goto test_failed_exit;
2374	}
2375
2376	bzero( &my_buffer[0], sizeof(my_buffer) );
2377	lseek( my_newfd, 0, SEEK_SET );
2378	my_count = read( my_newfd, &my_buffer[0], sizeof(my_buffer) );
2379	if ( my_count == -1 ) {
2380		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2381		goto test_failed_exit;
2382	}
2383	if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) {
2384		printf( "wrong data in test file. \n" );
2385		goto test_failed_exit;
2386	}
2387
2388	/* we do the above tests twice - once for dup and once for dup2 */
2389	if ( my_loop_counter < 1 ) {
2390		my_loop_counter++;
2391		close( my_newfd );
2392
2393		my_err = dup2( my_fd, my_newfd );
2394		if ( my_err == -1 ) {
2395			printf( "dup2 call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2396			goto test_failed_exit;
2397		}
2398
2399		goto redo;
2400	}
2401
2402	my_err = 0;
2403	goto test_passed_exit;
2404
2405test_failed_exit:
2406	my_err = -1;
2407
2408test_passed_exit:
2409	if ( my_fd != -1 )
2410		close( my_fd );
2411	if ( my_newfd != -1 )
2412		close( my_newfd );
2413	if ( my_pathp != NULL ) {
2414		remove( my_pathp );
2415		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2416	 }
2417	return( my_err );
2418}
2419
2420
2421/*  **************************************************************************************************************
2422 *	Test getrusage system call.
2423 *  **************************************************************************************************************
2424 */
2425int getrusage_test( void * the_argp )
2426{
2427	int				my_err;
2428	struct rusage	my_rusage;
2429
2430	my_err = getrusage( RUSAGE_SELF, &my_rusage );
2431	if ( my_err == -1 ) {
2432		printf( "getrusage failed with error %d - \"%s\" \n", errno, strerror( errno) );
2433		goto test_failed_exit;
2434	}
2435
2436	/* do a sanity check on the getrusage results */
2437	if ( my_rusage.ru_msgrcv > 1000 || my_rusage.ru_msgrcv < 0 ) {
2438		printf( "getrusage seems to report wrong data - ru_msgrcv looks odd. \n" );
2439		goto test_failed_exit;
2440	}
2441	if ( my_rusage.ru_nsignals > 1000 || my_rusage.ru_nsignals < 0 ) {
2442		printf( "getrusage seems to report wrong data - ru_nsignals looks odd. \n" );
2443		goto test_failed_exit;
2444	}
2445
2446	my_err = 0;
2447	goto test_passed_exit;
2448
2449test_failed_exit:
2450	my_err = -1;
2451
2452test_passed_exit:
2453	return( my_err );
2454}
2455
2456/*  **************************************************************************************************************
2457 *	Test getitimer, setitimer, sigaction, sigpending, sigprocmask, sigsuspend, sigwait system calls.
2458 *  **************************************************************************************************************
2459 */
2460
2461int		alarm_global = 0;
2462void test_alarm_handler( int the_arg );
2463void test_alarm_handler( int the_arg )
2464{
2465	alarm_global = 4;
2466	//printf( "test_alarm_handler - got here \n" );
2467	if ( the_arg == 0 ) {
2468	}
2469	return;
2470}
2471
2472void test_signal_handler( int the_arg );
2473void test_signal_handler( int the_arg )
2474{
2475	//printf( "test_signal_handler - got here \n" );
2476	if ( the_arg == 0 ) {
2477	}
2478	return;
2479}
2480
2481int signals_test( void * the_argp )
2482{
2483	int			my_err, my_status;
2484	int			my_fd = -1;
2485	char *		my_pathp = NULL;
2486	pid_t		my_pid, my_wait_pid;
2487	kern_return_t           my_kr;
2488
2489        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2490        if(my_kr != KERN_SUCCESS){
2491                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2492                goto test_failed_exit;
2493        }
2494
2495	*my_pathp = 0x00;
2496	strcat( my_pathp, &g_target_path[0] );
2497	strcat( my_pathp, "/" );
2498
2499	/* create a test file */
2500	my_err = create_random_name( my_pathp, 1 );
2501	if ( my_err != 0 ) {
2502		goto test_failed_exit;
2503	}
2504
2505	/*
2506	 * spin off a child process that we will use for signal related testing.
2507	 */
2508	my_pid = fork( );
2509	if ( my_pid == -1 ) {
2510		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2511		goto test_failed_exit;
2512	}
2513	if ( my_pid == 0 ) {
2514		/*
2515		 * child process - test signal related system calls.
2516		 */
2517		//int					my_counter;
2518		int					my_signal;
2519		sigset_t			my_sigset;
2520		struct sigaction	my_sigaction;
2521#ifdef MAC_OS_X_VERSION_10_5
2522#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
2523		/* If this is Leopard. To allow compiling for Inca x86_64 this definition cannot
2524		 * be included. But it is needed to compile on Leopard.
2525		 */
2526		struct __darwin_sigaltstack	my_sigaltstack;
2527#endif
2528#else
2529		struct sigaltstack	my_sigaltstack;
2530#endif
2531		struct itimerval    my_timer;
2532
2533
2534		/* test getting the current signal stack context */
2535		my_err = sigaltstack( NULL, &my_sigaltstack );
2536		if ( my_err == -1 ) {
2537			printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) );
2538			exit( -1 );
2539		}
2540		if ( (my_sigaltstack.ss_flags & SS_DISABLE) == 0 ) {
2541			printf( "sigaction must have failed - SS_DISABLE is cleared \n" );
2542			exit( -1 );
2543		}
2544
2545		/* set up to catch SIGUSR1 */
2546		my_sigaction.sa_handler = test_signal_handler;
2547		my_sigaction.sa_flags = SA_RESTART;
2548		my_sigaction.sa_mask = 0;
2549
2550		my_err = sigaction( SIGUSR1, &my_sigaction, NULL );
2551		if ( my_err == -1 ) {
2552			printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) );
2553			exit( -1 );
2554		}
2555
2556		/* now suspend until signal SIGUSR1 is sent */
2557		sigemptyset( &my_sigset );
2558		my_err = sigsuspend( &my_sigset );
2559		if ( my_err == -1 ) {
2560			if ( errno != EINTR ) {
2561				printf( "sigsuspend should have returned with errno EINTR \n" );
2562				exit( -1 );
2563			}
2564		}
2565
2566		/* block SIGUSR1 */
2567		sigemptyset( &my_sigset );
2568		sigaddset( &my_sigset, SIGUSR1 );
2569		if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) {
2570			printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2571			exit( -1 );
2572		}
2573		my_err = sigprocmask( SIG_BLOCK, &my_sigset, NULL );
2574		if ( my_err == -1 ) {
2575			printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2576			exit( -1 );
2577		}
2578
2579		/* make sure we are blocking SIGUSR1 */
2580		sigemptyset( &my_sigset );
2581		my_err = sigprocmask( 0, NULL, &my_sigset );
2582		if ( my_err == -1 ) {
2583			printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2584			exit( -1 );
2585		}
2586		if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) {
2587			printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2588			exit( -1 );
2589		}
2590
2591		/* our parent will send a 2nd SIGUSR1 signal which we should now see getting
2592		 * blocked.
2593		 */
2594		sigemptyset( &my_sigset );
2595		sigaddset( &my_sigset, SIGUSR1 );
2596		my_err = sigwait( &my_sigset, &my_signal );
2597		if ( my_err == -1 ) {
2598			printf( "sigwait failed with errno %d - %s \n", errno, strerror( errno ) );
2599			exit( -1 );
2600		}
2601		//printf( "%s - %d - signal 0x%02X %d \n", __FUNCTION__, __LINE__, my_signal, my_signal );
2602		if ( my_signal != SIGUSR1 ) {
2603			printf( "sigwait failed to catch a pending SIGUSR1 signal. \n" );
2604			exit( -1 );
2605		}
2606
2607		/* now unblock SIGUSR1 */
2608		sigfillset( &my_sigset );
2609		sigdelset( &my_sigset, SIGUSR1 );
2610		my_err = sigprocmask( SIG_UNBLOCK, &my_sigset, NULL );
2611		if ( my_err == -1 ) {
2612			printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2613			exit( -1 );
2614		}
2615		if ( sigismember( &my_sigset, SIGUSR1 ) != 0 ) {
2616			printf( "sigprocmask call failed to unblock SIGUSR1 \n" );
2617			exit( -1 );
2618		}
2619
2620		/* test get / setitimer */
2621		timerclear( &my_timer.it_interval );
2622		timerclear( &my_timer.it_value );
2623		my_err = setitimer( ITIMER_VIRTUAL, &my_timer, NULL );
2624		if ( my_err == -1 ) {
2625			printf( "setitimer - ITIMER_VIRTUAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2626			exit( -1 );
2627		}
2628		my_err = setitimer( ITIMER_PROF, &my_timer, NULL );
2629		if ( my_err == -1 ) {
2630			printf( "setitimer - ITIMER_PROF - failed with errno %d - %s \n", errno, strerror( errno ) );
2631			exit( -1 );
2632		}
2633
2634		/* set up to catch SIGALRM */
2635		alarm_global = 0;
2636		my_sigaction.sa_handler = test_alarm_handler;
2637		my_sigaction.sa_flags = SA_RESTART;
2638		my_sigaction.sa_mask = 0;
2639
2640		my_err = sigaction( SIGALRM, &my_sigaction, NULL );
2641		if ( my_err == -1 ) {
2642			printf( "sigaction - SIGALRM - failed with errno %d - %s \n", errno, strerror( errno ) );
2643			exit( -1 );
2644		}
2645
2646		/* set timer for half a second */
2647		my_timer.it_value.tv_usec = (1000000 / 2);
2648		my_err = setitimer( ITIMER_REAL, &my_timer, NULL );
2649		if ( my_err == -1 ) {
2650			printf( "setitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2651			exit( -1 );
2652		}
2653
2654		/* now suspend until signal SIGALRM is sent */
2655		sigfillset( &my_sigset );
2656		sigdelset( &my_sigset, SIGALRM );
2657		my_err = sigsuspend( &my_sigset );
2658		if ( my_err == -1 ) {
2659			if ( errno != EINTR ) {
2660				printf( "sigsuspend should have returned with errno EINTR \n" );
2661				exit( -1 );
2662			}
2663		}
2664		if ( alarm_global != 4 ) {
2665			printf( "setitimer test failed - did not catch SIGALRM \n" );
2666			exit( -1 );
2667		}
2668
2669		/* make sure ITIMER_REAL is now clear */
2670		my_timer.it_value.tv_sec = 44;
2671		my_timer.it_value.tv_usec = 44;
2672		my_err = getitimer( ITIMER_REAL, &my_timer );
2673		if ( my_err == -1 ) {
2674			printf( "getitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2675			exit( -1 );
2676		}
2677		if ( timerisset( &my_timer.it_value ) || timerisset( &my_timer.it_interval ) ) {
2678			printf( "ITIMER_REAL is set, but should not be \n" );
2679			exit( -1 );
2680		}
2681
2682		exit(0);
2683	}
2684
2685	/*
2686	 * parent process - let child set up to suspend then signal it with SIGUSR1
2687	 */
2688	sleep( 1 );
2689	my_err = kill( my_pid, SIGUSR1 );
2690	if ( my_err == -1 ) {
2691		printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2692		goto test_failed_exit;
2693	}
2694
2695	/* send 2nd signal to suspended child - which should be blocking SIGUSR1 signals */
2696	sleep( 1 );
2697	my_err = kill( my_pid, SIGUSR1 );
2698	if ( my_err == -1 ) {
2699		printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2700		goto test_failed_exit;
2701	}
2702
2703	/* wait for child to exit */
2704	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2705	if ( my_wait_pid == -1 ) {
2706		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2707		goto test_failed_exit;
2708	}
2709
2710	if ( WIFSIGNALED( my_status ) || ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) ) {
2711		goto test_failed_exit;
2712	}
2713
2714	my_err = 0;
2715	goto test_passed_exit;
2716
2717test_failed_exit:
2718	my_err = -1;
2719
2720test_passed_exit:
2721	if ( my_fd != -1 )
2722		close( my_fd );
2723	if ( my_pathp != NULL ) {
2724		remove( my_pathp );
2725		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2726	 }
2727	return( my_err );
2728}
2729
2730/*  **************************************************************************************************************
2731 *	Test getlogin, setlogin system calls.
2732 *  **************************************************************************************************************
2733 */
2734int getlogin_setlogin_test( void * the_argp )
2735{
2736	int			my_err, my_status;
2737	pid_t		my_pid, my_wait_pid;
2738	kern_return_t           my_kr;
2739
2740	if ( g_skip_setuid_tests != 0 ) {
2741		printf("\t skipping this test \n");
2742		my_err = 0;
2743		goto test_passed_exit;
2744	}
2745
2746	/*
2747	 * spin off a child process that we will use for testing.
2748	 */
2749	my_pid = fork( );
2750	if ( my_pid == -1 ) {
2751		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2752		goto test_failed_exit;
2753	}
2754	if ( my_pid == 0 ) {
2755		/*
2756		 * child process - do getlogin and setlogin testing.
2757		 */
2758		char *		my_namep = NULL;
2759		int		my_len;
2760		char *		my_new_namep = NULL;
2761
2762		my_namep = getlogin( );
2763		if ( my_namep == NULL ) {
2764			printf( "getlogin returned NULL name pointer \n" );
2765			my_err = -1;
2766			goto exit_child;
2767		}
2768
2769		my_len = strlen( my_namep ) + 4;
2770
2771	        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_namep, my_len, VM_FLAGS_ANYWHERE);
2772       		 if(my_kr != KERN_SUCCESS){
2773                	printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2774               		my_err = -1;
2775			goto exit_child;
2776        	}
2777
2778		bzero( (void *)my_new_namep, my_len );
2779
2780		strcat( my_new_namep, my_namep );
2781		strcat( my_new_namep, "2" );
2782
2783
2784		/* set new name */
2785		my_err = setlogin( my_new_namep );
2786		if ( my_err == -1 ) {
2787			printf( "When setting new login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) );
2788			my_err = -1;
2789			goto exit_child;
2790		}
2791
2792		/* make sure we set new name */
2793		my_namep = getlogin( );
2794		if ( my_namep == NULL ) {
2795			printf( "getlogin returned NULL name pointer \n" );
2796			my_err = -1;
2797			goto exit_child;
2798		}
2799
2800		if ( memcmp( my_namep, my_new_namep, strlen( my_new_namep ) ) != 0 ) {
2801			printf( "setlogin failed to set the new name \n" );
2802			my_err = -1;
2803			goto exit_child;
2804		}
2805
2806		/* reset to original name */
2807		my_len = strlen ( my_namep );
2808		my_namep[ my_len - 1 ] = '\0';
2809
2810		my_err = setlogin( my_namep );
2811		if ( my_err == -1 ) {
2812			printf( "When resetting login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) );
2813			my_err = -1;
2814			goto exit_child;
2815		}
2816
2817
2818		my_err = 0;
2819exit_child:
2820		if ( my_new_namep != NULL ) {
2821			vm_deallocate(mach_task_self(), (vm_address_t)my_new_namep, my_len);
2822		}
2823		exit( my_err );
2824	}
2825
2826	/* parent process -
2827	 * wait for child to exit
2828	 */
2829	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2830	if ( my_wait_pid == -1 ) {
2831		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2832		goto test_failed_exit;
2833	}
2834
2835	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2836		goto test_failed_exit;
2837	}
2838	my_err = 0;
2839	goto test_passed_exit;
2840
2841test_failed_exit:
2842	my_err = -1;
2843
2844test_passed_exit:
2845	return( my_err );
2846}
2847
2848/*  **************************************************************************************************************
2849 *	Test acct system call.
2850 *  **************************************************************************************************************
2851 */
2852int acct_test( void * the_argp )
2853{
2854	int		my_err, my_status;
2855	int		my_fd = -1;
2856	char *		my_pathp = NULL;
2857	struct acct *	my_acctp;
2858	pid_t		my_pid, my_wait_pid;
2859	ssize_t		my_count;
2860	char		my_buffer[ (sizeof(struct acct) + 32) ];
2861	kern_return_t           my_kr;
2862	int		acct_record_found;
2863	char *		test_bin_name = NULL;
2864
2865	if ( g_skip_setuid_tests != 0 ) {
2866		printf("\t skipping this test \n");
2867		my_err = 0;
2868		goto test_passed_exit;
2869	}
2870
2871	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2872        if(my_kr != KERN_SUCCESS){
2873                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2874                goto test_failed_exit;
2875        }
2876
2877	*my_pathp = 0x00;
2878	strcat( my_pathp, &g_target_path[0] );
2879	strcat( my_pathp, "/" );
2880
2881	/* create a test file */
2882	my_err = create_random_name( my_pathp, 1 );
2883	if ( my_err != 0 ) {
2884		goto test_failed_exit;
2885	}
2886
2887	/* enable process accounting */
2888	my_err =  acct( my_pathp );
2889	if ( my_err == -1 ) {
2890		printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2891		goto test_failed_exit;
2892	}
2893
2894	/*
2895	 * spin off a child process that we will use for testing.
2896	 */
2897	my_pid = fork( );
2898	if ( my_pid == -1 ) {
2899		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2900		goto test_failed_exit;
2901	}
2902	if ( my_pid == 0 ) {
2903		char *argv[2];		/* supply valid argv array to execv() */
2904		argv[0] = "/usr/bin/true";
2905		argv[1] = 0;
2906
2907		/*
2908		 * child process - do a little work then exit.
2909		 */
2910		my_err = execv( argv[0], argv);
2911		exit( 0 );
2912	}
2913
2914	/* parent process -
2915	 * wait for child to exit
2916	 */
2917	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2918	if ( my_wait_pid == -1 ) {
2919		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2920		goto test_failed_exit;
2921	}
2922
2923	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2924		printf("unexpected child exit status for accounting test load: %d\n", WEXITSTATUS( my_status));
2925		goto test_failed_exit;
2926	}
2927
2928	/* disable process accounting */
2929	my_err =  acct( NULL );
2930	if ( my_err == -1 ) {
2931		printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2932		goto test_failed_exit;
2933	}
2934
2935	/* now verify that there is accounting info in the log file */
2936	my_fd = open( my_pathp, O_RDONLY, 0 );
2937	if ( my_fd == -1 ) {
2938		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2939		goto test_failed_exit;
2940	}
2941
2942	lseek( my_fd, 0, SEEK_SET );
2943	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
2944	acct_record_found = 0;
2945	test_bin_name = "true";
2946
2947	while(1) {
2948
2949  		my_count = read( my_fd, &my_buffer[0], sizeof(struct acct) );
2950
2951  		if ( my_count == -1 ) {
2952    			printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2953    			goto test_failed_exit;
2954  		}
2955
2956  		if ( my_count < sizeof(struct acct)) {
2957    			/* Indicates EOF or misaligned file size */
2958			printf("Reached end of accounting records with last read count: %d\n", my_count);
2959			break;
2960  		}
2961
2962  		my_acctp = (struct acct *) &my_buffer[0];
2963  		/* first letters in ac_comm should match the name of the executable */
2964  		if ( (getuid() == my_acctp->ac_uid) && (getgid() == my_acctp->ac_gid) &&
2965		     (!strncmp(my_acctp->ac_comm, test_bin_name, strlen(test_bin_name))) ) {
2966    			/* Expected accounting record found */
2967    			acct_record_found = 1;
2968    			break;
2969  		}
2970
2971 	}
2972
2973	if (acct_record_found) {
2974  		my_err = 0;
2975  		goto test_passed_exit;
2976 	} else {
2977   		printf( "------------------------\n" );
2978   		printf( "Expected Accounting Record for child process %s not found\n", test_bin_name );
2979   		printf( "Expected uid: %lu Expected gid: %lu\n" , (unsigned long) getuid(), (unsigned long) getgid() );
2980   		printf( "Account file path: %s\n",  my_pathp );
2981   		goto test_failed_exit;
2982 	}
2983
2984test_failed_exit:
2985	my_err = -1;
2986
2987test_passed_exit:
2988	if ( my_fd != -1 )
2989		close( my_fd );
2990	if ( my_pathp != NULL ) {
2991		remove( my_pathp );
2992		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2993	 }
2994	return( my_err );
2995}
2996
2997void print_acct_debug_strings( char * my_ac_comm )
2998{
2999	char	my_cmd_str[11]; /* sizeof(acct_cmd) + 1 for '\0' if acct_cmd is bogus */
3000	char	my_hex_str[128];
3001	int 	i;
3002
3003	my_hex_str[0] = '\0';
3004	for(i = 0; i < 10; i++)
3005	{
3006		sprintf( my_hex_str, "%s \'0x%x\' ", my_hex_str, my_ac_comm[i]);
3007	}
3008
3009	memccpy(my_cmd_str, my_ac_comm, '\0', 10);
3010	my_cmd_str[10] = '\0'; /* In case ac_comm was bogus */
3011
3012
3013	printf( "my_acctp->ac_comm = \"%s\" (should begin with: \"tr\")\n", my_cmd_str);
3014	printf( "my_acctp->ac_comm = \"%s\"\n", my_hex_str);
3015	printf( "------------------------\n" );
3016}
3017
3018
3019/*  **************************************************************************************************************
3020 *	Test ioctl system calls.
3021 *  **************************************************************************************************************
3022 */
3023int ioctl_test( void * the_argp )
3024{
3025	int					my_err, my_result;
3026	int					my_fd = -1;
3027	struct statfs *		my_infop;
3028	char *				my_ptr;
3029    int					my_blksize;
3030    long long			my_block_count;
3031	char				my_name[ 128 ];
3032
3033	my_result = getmntinfo( &my_infop, MNT_NOWAIT );
3034	if ( my_result < 1 ) {
3035		printf( "getmntinfo failed with error %d - \"%s\" \n", errno, strerror( errno) );
3036		goto test_failed_exit;
3037	}
3038
3039	/* make this a raw device */
3040	strcpy( &my_name[0], &my_infop->f_mntfromname[0] );
3041	if ( (my_ptr = strrchr( &my_name[0], '/' )) != 0 ) {
3042		if ( my_ptr[1] != 'r' ) {
3043			my_ptr[ strlen( my_ptr ) ] = 0x00;
3044			memmove( &my_ptr[2], &my_ptr[1], (strlen( &my_ptr[1] ) + 1) );
3045			my_ptr[1] = 'r';
3046		}
3047	}
3048
3049	my_fd = open(&my_name[0], O_RDONLY );
3050	if ( my_fd == -1 ) {
3051		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3052		goto test_failed_exit;
3053	}
3054
3055    /* obtain the size of the media (in blocks) */
3056	my_err = ioctl( my_fd, DKIOCGETBLOCKCOUNT, &my_block_count );
3057	if ( my_err == -1 ) {
3058		printf( "ioctl DKIOCGETBLOCKCOUNT failed with error %d - \"%s\" \n", errno, strerror( errno) );
3059		goto test_failed_exit;
3060	}
3061
3062    /* obtain the block size of the media */
3063	my_err = ioctl( my_fd, DKIOCGETBLOCKSIZE, &my_blksize );
3064	if ( my_err == -1 ) {
3065		printf( "ioctl DKIOCGETBLOCKSIZE failed with error %d - \"%s\" \n", errno, strerror( errno) );
3066		goto test_failed_exit;
3067	}
3068	//printf( "my_block_count %qd my_blksize %d \n", my_block_count, my_blksize );
3069
3070	/* make sure the returned data looks somewhat valid */
3071	if ( my_blksize < 0 || my_blksize > (1024 * 1000) ) {
3072		printf( "ioctl appears to have returned incorrect block size data \n" );
3073		goto test_failed_exit;
3074	}
3075
3076	my_err = 0;
3077	goto test_passed_exit;
3078
3079test_failed_exit:
3080	my_err = -1;
3081
3082test_passed_exit:
3083	if ( my_fd != -1 )
3084		close( my_fd );
3085	return( my_err );
3086}
3087
3088/*  **************************************************************************************************************
3089 *	Test mkdir, rmdir, umask system calls.
3090 *  **************************************************************************************************************
3091 */
3092int mkdir_rmdir_umask_test( void * the_argp )
3093{
3094	int				my_err;
3095	int				my_fd = -1;
3096	int				did_umask = 0;
3097	char *			my_pathp = NULL;
3098	mode_t			my_orig_mask;
3099	struct stat		my_sb;
3100	kern_return_t           my_kr;
3101
3102        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3103        if(my_kr != KERN_SUCCESS){
3104                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3105                goto test_failed_exit;
3106        }
3107
3108	*my_pathp = 0x00;
3109	strcat( my_pathp, &g_target_path[0] );
3110	strcat( my_pathp, "/" );
3111
3112	/* get a unique name to use with mkdir */
3113	my_err = create_random_name( my_pathp, 0 );
3114	if ( my_err != 0 ) {
3115		printf( "create_random_name failed with error %d\n", my_err );
3116		goto test_failed_exit;
3117	}
3118
3119	/* set umask to clear WX for other and group and clear X for user */
3120	my_orig_mask = umask( (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) );
3121	did_umask = 1;
3122
3123	/* create a directory with RWX for user, group, other (which should be limited by umask) */
3124	my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3125	if ( my_err == -1 ) {
3126		printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3127		goto test_failed_exit;
3128	}
3129
3130	/* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/
3131	my_err = stat( my_pathp, &my_sb );
3132	if ( my_err != 0 ) {
3133		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3134		goto test_failed_exit;
3135	}
3136	if ( (my_sb.st_mode & (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH)) != 0 ) {
3137		printf( "umask did not limit modes as it should have \n" );
3138		goto test_failed_exit;
3139	}
3140
3141	/* get rid of our test directory */
3142	my_err = rmdir( my_pathp );
3143	if ( my_err == -1 ) {
3144		printf( "rmdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3145		goto test_failed_exit;
3146	}
3147	my_err = 0;
3148	goto test_passed_exit;
3149
3150test_failed_exit:
3151	my_err = -1;
3152
3153test_passed_exit:
3154	if ( my_fd != -1 )
3155		close( my_fd );
3156	if ( my_pathp != NULL ) {
3157		rmdir( my_pathp );
3158		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3159	 }
3160	 if ( did_umask != 0 ) {
3161		umask( my_orig_mask );
3162	 }
3163
3164	return( my_err );
3165}
3166
3167/*  **************************************************************************************************************
3168 *	Test chroot system call.
3169 *  **************************************************************************************************************
3170 */
3171int chroot_test( void * the_argp )
3172{
3173	int			my_err, my_status;
3174	pid_t		my_pid, my_wait_pid;
3175	char *		my_pathp = NULL;
3176	kern_return_t           my_kr;
3177
3178	if ( g_skip_setuid_tests != 0 ) {
3179		printf("\t skipping this test \n");
3180		my_err = 0;
3181		goto test_passed_exit;
3182	}
3183
3184        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3185        if(my_kr != KERN_SUCCESS){
3186                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3187                goto test_failed_exit;
3188        }
3189
3190	*my_pathp = 0x00;
3191	strcat( my_pathp, &g_target_path[0] );
3192	strcat( my_pathp, "/" );
3193
3194	/* get a unique name for our test directory */
3195	my_err = create_random_name( my_pathp, 0 );
3196	if ( my_err != 0 ) {
3197		goto test_failed_exit;
3198	}
3199
3200	/* create a test directory */
3201	my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3202	if ( my_err == -1 ) {
3203		printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3204		goto test_failed_exit;
3205	}
3206
3207	/*
3208	 * spin off a child process that we will use for testing.
3209	 */
3210	my_pid = fork( );
3211	if ( my_pid == -1 ) {
3212		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3213		goto test_failed_exit;
3214	}
3215	if ( my_pid == 0 ) {
3216		/*
3217		 * child process - do getlogin and setlogin testing.
3218		 */
3219		struct stat		my_sb;
3220
3221		/* change our root to our new test directory */
3222		my_err = chroot( my_pathp );
3223		if ( my_err != 0 ) {
3224			printf( "chroot failed with error %d - \"%s\" \n", errno, strerror( errno) );
3225			exit( -1 );
3226		}
3227
3228		/* verify root directory is now an empty directory */
3229		my_err = stat( "/", &my_sb );
3230		if ( my_err != 0 ) {
3231			printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3232			exit( -1 );
3233		}
3234		if ( my_sb.st_nlink > 2 ) {
3235			printf( "root dir should be emnpty! \n" );
3236			exit( -1 );
3237		}
3238		exit( 0 );
3239	}
3240
3241	/* parent process -
3242	 * wait for child to exit
3243	 */
3244	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3245	if ( my_wait_pid == -1 ) {
3246		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3247		goto test_failed_exit;
3248	}
3249
3250	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3251		printf( "bad exit status\n" );
3252		goto test_failed_exit;
3253	}
3254
3255	my_err = 0;
3256	goto test_passed_exit;
3257
3258test_failed_exit:
3259	my_err = -1;
3260
3261test_passed_exit:
3262	if ( my_pathp != NULL ) {
3263		my_err = rmdir( my_pathp );
3264		if ( my_err != 0 ) {
3265			printf( "rmdir failed with error %d - \"%s\" path %p\n", errno, strerror( errno), my_pathp );
3266		}
3267		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3268	}
3269	return( my_err );
3270}
3271
3272/*  **************************************************************************************************************
3273 *	Test getpgrp, getpgid, getsid, setpgid, setpgrp, setsid system calls.
3274 *  **************************************************************************************************************
3275 */
3276int process_group_test( void * the_argp )
3277{
3278	int		my_err = 0, i = 0;
3279	pid_t		my_session_id, my_pid, my_process_group;
3280
3281	/* get current session ID, pgid, and pid */
3282	my_session_id = getsid( 0 );
3283	if ( my_session_id == -1 ) {
3284		printf( "getsid call failed with error %d - \"%s\" \n",
3285				errno, strerror( errno ) );
3286		goto test_failed_exit;
3287	}
3288
3289	my_pid = getpid( );
3290	my_process_group = getpgrp( );
3291
3292	/* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */
3293	if ( my_process_group != getpgid( 0 ) ) {
3294		printf( "getpgrp and getpgid did not return the same process group ID \n" );
3295		printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group );
3296		goto test_failed_exit;
3297	}
3298
3299	if ( my_pid == my_process_group ) {
3300		/* we are process group leader */
3301		my_err = setsid( );
3302		if ( my_err == 0  || errno != EPERM ) {
3303			printf( "setsid call should have failed with EPERM\n" );
3304			goto test_failed_exit;
3305		}
3306	} else {
3307		/* we are not process group leader: try creating new session */
3308		my_err = setsid( );
3309		if ( my_err == -1 ) {
3310			printf( "setsid call failed with error %d - \"%s\" \n",
3311					errno, strerror( errno ) );
3312			goto test_failed_exit;
3313		}
3314
3315		if ( my_process_group == getpgid( 0 ) ) {
3316			printf( "process group was not reset \n" );
3317			goto test_failed_exit;
3318		}
3319	}
3320
3321	/* find an unused process group ID */
3322	for ( i = 10000; i < 1000000; i++ ) {
3323		my_process_group = getpgid( i );
3324		if ( my_process_group == -1 ) {
3325			break;
3326		}
3327	}
3328
3329	/* this should fail */
3330	my_err = setpgid( 0, my_process_group );
3331	if ( my_err != -1 ) {
3332		printf( "setpgid should have failed, but did not \n" );
3333		goto test_failed_exit;
3334	}
3335
3336	my_err = 0;
3337	goto test_passed_exit;
3338
3339test_failed_exit:
3340	my_err = -1;
3341
3342test_passed_exit:
3343	return( my_err );
3344}
3345
3346/*  **************************************************************************************************************
3347 *	Test fcntl system calls.
3348 *  **************************************************************************************************************
3349 */
3350int fcntl_test( void * the_argp )
3351{
3352	int			my_err, my_result, my_tmep;
3353	int			my_fd = -1;
3354	int			my_newfd = -1;
3355	char *		my_pathp = NULL;
3356	kern_return_t           my_kr;
3357
3358        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3359        if(my_kr != KERN_SUCCESS){
3360                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3361                goto test_failed_exit;
3362        }
3363
3364	*my_pathp = 0x00;
3365	strcat( my_pathp, &g_target_path[0] );
3366	strcat( my_pathp, "/" );
3367
3368	/* create a test file */
3369	my_err = create_random_name( my_pathp, 1 );
3370	if ( my_err != 0 ) {
3371		goto test_failed_exit;
3372	}
3373
3374	/* open our test file and use fcntl to get / set file descriptor flags */
3375	my_fd = open( my_pathp, O_RDONLY, 0 );
3376	if ( my_fd == -1 ) {
3377		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3378		goto test_failed_exit;
3379	}
3380
3381	my_result = fcntl( my_fd, F_GETFD, 0 );
3382	if ( my_result == -1 ) {
3383		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3384		goto test_failed_exit;
3385	}
3386
3387	my_tmep = (my_result & FD_CLOEXEC);
3388	if ( my_tmep ) {
3389		/* FD_CLOEXEC is on, let's turn it off */
3390		my_result = fcntl( my_fd, F_SETFD, 0 );
3391	}
3392	else {
3393		/* FD_CLOEXEC is off, let's turn it on */
3394		my_result = fcntl( my_fd, F_SETFD, 1 );
3395	}
3396	if ( my_result == -1 ) {
3397		printf( "fcntl - F_SETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3398		goto test_failed_exit;
3399	}
3400
3401	/* now check to see if it is set correctly */
3402	my_result = fcntl( my_fd, F_GETFD, 0 );
3403	if ( my_result == -1 ) {
3404		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3405		goto test_failed_exit;
3406	}
3407	if ( my_tmep == (my_result & 0x01) ) {
3408		printf( "fcntl - F_SETFD failed to set FD_CLOEXEC correctly!!! \n" );
3409		goto test_failed_exit;
3410	}
3411
3412	/* dup it to a new fd with FD_CLOEXEC forced on */
3413
3414	my_result = fcntl( my_fd, F_DUPFD_CLOEXEC, 0);
3415	if ( my_result == -1 ) {
3416		printf( "fcntl - F_DUPFD_CLOEXEC - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3417		goto test_failed_exit;
3418	}
3419	my_newfd = my_result;
3420
3421	/* check to see that it too is marked with FD_CLOEXEC */
3422
3423	my_result = fcntl( my_newfd, F_GETFD, 0);
3424	if ( my_result == -1 ) {
3425		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3426		goto test_failed_exit;
3427	}
3428	if ( (my_result & FD_CLOEXEC) == 0 ) {
3429		printf( "fcntl - F_DUPFD_CLOEXEC failed to set FD_CLOEXEC!!! \n" );
3430		goto test_failed_exit;
3431	}
3432
3433	close( my_newfd );
3434	my_newfd = -1;
3435
3436	/* While we're here, dup it via an open of /dev/fd/<fd> .. */
3437
3438	{
3439		char devfdpath[PATH_MAX];
3440
3441		(void) snprintf( devfdpath, sizeof (devfdpath),
3442			"/dev/fd/%u", my_fd );
3443		my_result = open( devfdpath, O_RDONLY | O_CLOEXEC );
3444	}
3445	if ( my_result == -1 ) {
3446		printf( "open call failed on /dev/fd/%u with error %d - \"%s\" \n", my_fd, errno, strerror( errno) );
3447		goto test_failed_exit;
3448	}
3449	my_newfd = my_result;
3450
3451	/* check to see that it too is marked with FD_CLOEXEC */
3452
3453	my_result = fcntl( my_newfd, F_GETFD, 0);
3454	if ( my_result == -1 ) {
3455		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3456		goto test_failed_exit;
3457	}
3458	if ( (my_result & FD_CLOEXEC) == 0 ) {
3459		printf( "fcntl - O_CLOEXEC open of /dev/fd/%u failed to set FD_CLOEXEC!!! \n", my_fd );
3460		goto test_failed_exit;
3461	}
3462	close ( my_newfd );
3463	my_newfd = -1;
3464	my_err = 0;
3465	goto test_passed_exit;
3466
3467test_failed_exit:
3468	my_err = -1;
3469
3470test_passed_exit:
3471	if ( my_newfd != -1)
3472		close ( my_newfd );
3473	if ( my_fd != -1 )
3474		close( my_fd );
3475	if ( my_pathp != NULL ) {
3476		remove( my_pathp );
3477		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3478	 }
3479	return( my_err );
3480}
3481
3482/*  **************************************************************************************************************
3483 *	Test getpriority, setpriority system calls.
3484 *  **************************************************************************************************************
3485 */
3486int getpriority_setpriority_test( void * the_argp )
3487{
3488	int			my_err;
3489	int			my_priority;
3490	int			my_new_priority;
3491
3492	/* getpriority returns scheduling priority so -1 is a valid value */
3493	errno = 0;
3494	my_priority = getpriority( PRIO_PROCESS, 0 );
3495	if ( my_priority == -1 && errno != 0 ) {
3496		printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3497		goto test_failed_exit;
3498	}
3499
3500	/* change scheduling priority */
3501	my_new_priority = (my_priority == PRIO_MIN) ? (my_priority + 10) : (PRIO_MIN);
3502	my_err = setpriority( PRIO_PROCESS, 0, my_new_priority );
3503	if ( my_err == -1 ) {
3504		printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3505		goto test_failed_exit;
3506	}
3507
3508	/* verify change */
3509	errno = 0;
3510	my_priority = getpriority( PRIO_PROCESS, 0 );
3511	if ( my_priority == -1 && errno != 0 ) {
3512		printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3513		goto test_failed_exit;
3514	}
3515
3516	if ( my_priority != my_new_priority ) {
3517		printf( "setpriority - failed to set correct scheduling priority \n" );
3518		goto test_failed_exit;
3519	}
3520
3521	/* reset scheduling priority */
3522	my_err = setpriority( PRIO_PROCESS, 0, 0 );
3523	if ( my_err == -1 ) {
3524		printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3525		goto test_failed_exit;
3526	}
3527
3528	my_err = 0;
3529	goto test_passed_exit;
3530
3531test_failed_exit:
3532	my_err = -1;
3533
3534test_passed_exit:
3535	return( my_err );
3536}
3537
3538/*  **************************************************************************************************************
3539 *	Test futimes, gettimeofday, settimeofday, utimes system calls.
3540 *  **************************************************************************************************************
3541 */
3542int time_tests( void * the_argp )
3543{
3544	int					my_err;
3545	int					my_fd = -1;
3546	char *				my_pathp = NULL;
3547	struct timeval		my_orig_time;
3548	struct timeval		my_temp_time;
3549	struct timeval		my_utimes[4];
3550	struct timezone		my_tz;
3551	struct stat			my_sb;
3552	kern_return_t           my_kr;
3553
3554	if ( g_skip_setuid_tests != 0 ) {
3555		printf( "\t skipping this test \n" );
3556		my_err = 0;
3557		goto test_passed_exit;
3558	}
3559
3560        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3561        if(my_kr != KERN_SUCCESS){
3562                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3563                goto test_failed_exit;
3564        }
3565
3566	*my_pathp = 0x00;
3567	strcat( my_pathp, &g_target_path[0] );
3568	strcat( my_pathp, "/" );
3569
3570	/* create a test file */
3571	my_err = create_random_name( my_pathp, 1 );
3572	if ( my_err != 0 ) {
3573		goto test_failed_exit;
3574	}
3575
3576	my_err = gettimeofday( &my_orig_time, &my_tz );
3577	if ( my_err == -1 ) {
3578		printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3579		goto test_failed_exit;
3580	}
3581	//printf( "tv_sec %d tv_usec %ld \n", my_orig_time.tv_sec, my_orig_time.tv_usec );
3582
3583	my_temp_time = my_orig_time;
3584	my_temp_time.tv_sec -= 60;
3585	my_err = settimeofday( &my_temp_time, NULL );
3586	if ( my_err == -1 ) {
3587		printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3588		goto test_failed_exit;
3589	}
3590
3591	my_err = gettimeofday( &my_temp_time, NULL );
3592	if ( my_err == -1 ) {
3593		printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3594		goto test_failed_exit;
3595	}
3596	//printf( "tv_sec %d tv_usec %ld \n", my_temp_time.tv_sec, my_temp_time.tv_usec );
3597	if ( my_orig_time.tv_sec <= my_temp_time.tv_sec ) {
3598		printf( "settimeofday did not set correct time \n" );
3599		goto test_failed_exit;
3600	}
3601
3602	/* set time back to original value plus 1 second */
3603	my_temp_time = my_orig_time;
3604	my_temp_time.tv_sec += 1;
3605	my_err = settimeofday( &my_temp_time, NULL );
3606	if ( my_err == -1 ) {
3607		printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3608		goto test_failed_exit;
3609	}
3610
3611	/* test utimes and futimes - get current access and mod times then change them */
3612	my_err = stat( my_pathp, &my_sb );
3613	if ( my_err != 0 ) {
3614		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3615		goto test_failed_exit;
3616	}
3617	TIMESPEC_TO_TIMEVAL( &my_utimes[0], &my_sb.st_atimespec );
3618	TIMESPEC_TO_TIMEVAL( &my_utimes[1], &my_sb.st_mtimespec );
3619	my_utimes[0].tv_sec -= 120;		/* make access time 2 minutes older */
3620	my_utimes[1].tv_sec -= 120;		/* make mod time 2 minutes older */
3621
3622	my_err = utimes( my_pathp, &my_utimes[0] );
3623	if ( my_err == -1 ) {
3624		printf( "utimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3625		goto test_failed_exit;
3626	}
3627
3628	/* make sure the correct times are set */
3629	my_err = stat( my_pathp, &my_sb );
3630	if ( my_err != 0 ) {
3631		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3632		goto test_failed_exit;
3633	}
3634	TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3635	TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3636	if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3637		 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3638		printf( "utimes failed to set access and mod times \n" );
3639		goto test_failed_exit;
3640	}
3641
3642	my_fd = open( my_pathp, O_RDWR, 0 );
3643	if ( my_fd == -1 ) {
3644		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3645		goto test_failed_exit;
3646	}
3647
3648	my_utimes[0].tv_sec -= 120;  /* make access time 2 minutes older */
3649	my_utimes[1].tv_sec -= 120;  /* make mod time 2 minutes older */
3650	my_err = futimes( my_fd, &my_utimes[0] );
3651	if ( my_err == -1 ) {
3652		printf( "futimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3653		goto test_failed_exit;
3654	}
3655
3656	/* make sure the correct times are set */
3657	my_err = stat( my_pathp, &my_sb );
3658	if ( my_err != 0 ) {
3659		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3660		goto test_failed_exit;
3661	}
3662	TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3663	TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3664	if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3665		 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3666		printf( "futimes failed to set access and mod times \n" );
3667		goto test_failed_exit;
3668	}
3669
3670	my_err = 0;
3671	goto test_passed_exit;
3672
3673test_failed_exit:
3674	my_err = -1;
3675
3676test_passed_exit:
3677	if ( my_fd != -1 )
3678		close( my_fd );
3679	if ( my_pathp != NULL ) {
3680		remove( my_pathp );
3681		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3682	 }
3683	return( my_err );
3684}
3685
3686/*  **************************************************************************************************************
3687 *	Test rename, stat system calls.
3688 *  **************************************************************************************************************
3689 */
3690int rename_test( void * the_argp )
3691{
3692	int				my_err;
3693	char *			my_pathp = NULL;
3694	char *			my_new_pathp = NULL;
3695	ino_t			my_file_id;
3696	struct stat		my_sb;
3697	kern_return_t           my_kr;
3698
3699        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3700        if(my_kr != KERN_SUCCESS){
3701                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3702                goto test_failed_exit;
3703        }
3704
3705	*my_pathp = 0x00;
3706	strcat( my_pathp, &g_target_path[0] );
3707	strcat( my_pathp, "/" );
3708
3709	/* create a test file */
3710	my_err = create_random_name( my_pathp, 1 );
3711	if ( my_err != 0 ) {
3712		goto test_failed_exit;
3713	}
3714
3715        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3716        if(my_kr != KERN_SUCCESS){
3717                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3718                goto test_failed_exit;
3719        }
3720
3721	*my_new_pathp = 0x00;
3722	strcat( my_new_pathp, &g_target_path[0] );
3723	strcat( my_new_pathp, "/" );
3724
3725	/* get a unique name for our rename test */
3726	my_err = create_random_name( my_new_pathp, 0 );
3727	if ( my_err != 0 ) {
3728		goto test_failed_exit;
3729	}
3730
3731	/* save file ID for later use */
3732	my_err = stat( my_pathp, &my_sb );
3733	if ( my_err != 0 ) {
3734		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3735		goto test_failed_exit;
3736	}
3737	my_file_id = my_sb.st_ino;
3738
3739	/* test rename */
3740	my_err = rename( my_pathp, my_new_pathp );
3741	if ( my_err == -1 ) {
3742		printf( "rename - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3743		goto test_failed_exit;
3744	}
3745
3746	/* make sure old name is no longer there */
3747	my_err = stat( my_pathp, &my_sb );
3748	if ( my_err == 0 ) {
3749		printf( "rename call failed - found old name \n" );
3750		goto test_failed_exit;
3751	}
3752
3753	/* make sure new name is there and is correct file id */
3754	my_err = stat( my_new_pathp, &my_sb );
3755	if ( my_err != 0 ) {
3756		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3757		goto test_failed_exit;
3758	}
3759	if ( my_file_id != my_sb.st_ino ) {
3760		printf( "rename failed - wrong file id \n" );
3761		goto test_failed_exit;
3762	}
3763
3764	my_err = 0;
3765	goto test_passed_exit;
3766
3767test_failed_exit:
3768	my_err = -1;
3769
3770test_passed_exit:
3771	if ( my_pathp != NULL ) {
3772		remove( my_pathp );
3773		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3774	 }
3775	if ( my_new_pathp != NULL ) {
3776		remove( my_new_pathp );
3777		vm_deallocate(mach_task_self(), (vm_address_t)my_new_pathp, PATH_MAX);
3778	 }
3779	return( my_err );
3780}
3781
3782/*  **************************************************************************************************************
3783 *	Test locking system calls.
3784 *  **************************************************************************************************************
3785 */
3786int locking_test( void * the_argp )
3787{
3788	int			my_err, my_status;
3789	pid_t		my_pid, my_wait_pid;
3790	int			my_fd = -1;
3791	char *		my_pathp = NULL;
3792	kern_return_t           my_kr;
3793
3794        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3795        if(my_kr != KERN_SUCCESS){
3796                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3797                goto test_failed_exit;
3798        }
3799
3800	*my_pathp = 0x00;
3801	strcat( my_pathp, &g_target_path[0] );
3802	strcat( my_pathp, "/" );
3803
3804	/* create a test file */
3805	my_err = create_random_name( my_pathp, 1 );
3806	if ( my_err != 0 ) {
3807		goto test_failed_exit;
3808	}
3809
3810	/* test flock */
3811	my_fd = open( my_pathp, O_RDWR, 0 );
3812	if ( my_fd == -1 ) {
3813		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3814		goto test_failed_exit;
3815	}
3816
3817	my_err =  flock( my_fd, LOCK_EX );
3818	if ( my_err == -1 ) {
3819		printf( "flock - LOCK_EX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3820		goto test_failed_exit;
3821	}
3822
3823	/*
3824	 * spin off a child process that we will use for testing.
3825	 */
3826	my_pid = fork( );
3827	if ( my_pid == -1 ) {
3828		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3829		goto test_failed_exit;
3830	}
3831	if ( my_pid == 0 ) {
3832		/*
3833		 * child process.
3834		 */
3835		int			my_child_fd = -1;
3836		int			my_child_err;
3837
3838		my_child_fd = open( my_pathp, O_RDWR, 0 );
3839		if ( my_child_fd == -1 ) {
3840			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3841			my_child_err = -1;
3842			goto child_exit;
3843		}
3844
3845		my_err =  flock( my_child_fd, (LOCK_EX | LOCK_NB) );
3846		if ( my_err == -1 ) {
3847			if ( errno != EWOULDBLOCK ) {
3848				printf( "flock call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3849				my_child_err = -1;
3850				goto child_exit;
3851			}
3852		}
3853		else {
3854			printf( "flock call should have failed with EWOULDBLOCK err \n" );
3855			my_child_err = -1;
3856			goto child_exit;
3857		}
3858		my_child_err = 0;
3859child_exit:
3860		if ( my_child_fd != -1 )
3861			close( my_child_fd );
3862		exit( my_child_err );
3863	}
3864
3865	/* parent process -
3866	 * wait for child to exit
3867	 */
3868	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3869	if ( my_wait_pid == -1 ) {
3870		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3871		goto test_failed_exit;
3872	}
3873
3874	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3875		goto test_failed_exit;
3876	}
3877
3878	my_err =  flock( my_fd, LOCK_UN );
3879	if ( my_err == -1 ) {
3880		printf( "flock - LOCK_UN - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3881		goto test_failed_exit;
3882	}
3883
3884	my_err = 0;
3885	goto test_passed_exit;
3886
3887test_failed_exit:
3888	my_err = -1;
3889
3890test_passed_exit:
3891	if ( my_fd != -1 )
3892		close( my_fd );
3893	if ( my_pathp != NULL ) {
3894		remove( my_pathp );
3895		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3896	 }
3897	return( my_err );
3898}
3899
3900/*  **************************************************************************************************************
3901 *	Test mkfifo system calls.
3902 *  **************************************************************************************************************
3903 */
3904int mkfifo_test( void * the_argp )
3905{
3906	int			my_err, my_status;
3907	pid_t		my_pid, my_wait_pid;
3908	int			my_fd = -1;
3909	char *		my_pathp = NULL;
3910	ssize_t		my_result;
3911	off_t		my_current_offset;
3912	kern_return_t           my_kr;
3913
3914        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3915        if(my_kr != KERN_SUCCESS){
3916                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3917                goto test_failed_exit;
3918        }
3919
3920	*my_pathp = 0x00;
3921	strcat( my_pathp, &g_target_path[0] );
3922	strcat( my_pathp, "/" );
3923
3924	/* get unique name for our fifo */
3925	my_err = create_random_name( my_pathp, 0 );
3926	if ( my_err != 0 ) {
3927		goto test_failed_exit;
3928	}
3929
3930	my_err = mkfifo( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
3931	if ( my_err != 0 ) {
3932		printf( "mkfifo failed with errno %d - %s. \n", errno, strerror( errno ) );
3933		goto test_failed_exit;
3934	}
3935
3936	/*
3937	 * spin off a child process that we will use for testing.
3938	 */
3939	my_pid = fork( );
3940	if ( my_pid == -1 ) {
3941		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3942		goto test_failed_exit;
3943	}
3944	if ( my_pid == 0 ) {
3945		/*
3946		 * child process.
3947		 */
3948		int			my_child_fd = -1;
3949		int			my_child_err;
3950		char		my_buffer[64];
3951
3952		/* open read end of fifo */
3953		my_child_fd = open( my_pathp, O_RDWR, 0 );
3954		if ( my_child_fd == -1 ) {
3955			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3956			my_child_err = -1;
3957			goto child_exit;
3958		}
3959
3960		/* read message from parent */
3961		bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
3962		my_result = read( my_child_fd, &my_buffer[0], sizeof(my_buffer) );
3963		if ( my_result == -1 ) {
3964			printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3965			my_child_err = -1;
3966			goto child_exit;
3967		}
3968		if ( strcmp( "parent to child", &my_buffer[0] ) != 0 ) {
3969			printf( "read wrong message from parent \n" );
3970			my_child_err = -1;
3971			goto child_exit;
3972		}
3973
3974		my_child_err = 0;
3975child_exit:
3976		if ( my_child_fd != -1 )
3977			close( my_child_fd );
3978		exit( my_child_err );
3979	}
3980
3981	/* parent process - open write end of fifo
3982	 */
3983	my_fd = open( my_pathp, O_WRONLY, 0 );
3984	if ( my_fd == -1 ) {
3985		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3986		goto test_failed_exit;
3987	}
3988
3989	/* make sure we can't seek on a fifo */
3990	my_current_offset = lseek( my_fd, 0, SEEK_CUR );
3991	if ( my_current_offset != -1 ) {
3992		printf( "lseek on fifo should fail but did not \n" );
3993		goto test_failed_exit;
3994	}
3995
3996	my_result = write( my_fd, "parent to child", 15 );
3997	if ( my_result == -1 ) {
3998		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3999		goto test_failed_exit;
4000	}
4001
4002	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
4003	if ( my_wait_pid == -1 ) {
4004		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
4005		goto test_failed_exit;
4006	}
4007
4008	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
4009		goto test_failed_exit;
4010	}
4011
4012	my_err = 0;
4013	goto test_passed_exit;
4014
4015test_failed_exit:
4016	my_err = -1;
4017
4018test_passed_exit:
4019	if ( my_fd != -1 )
4020		close( my_fd );
4021	if ( my_pathp != NULL ) {
4022		remove( my_pathp );
4023		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4024	 }
4025	return( my_err );
4026}
4027
4028/*  **************************************************************************************************************
4029 *	Test quotactl system calls.
4030 *  **************************************************************************************************************
4031 */
4032int quotactl_test( void * the_argp )
4033{
4034	int				my_err;
4035	int				is_quotas_on = 0;
4036	struct dqblk	my_quota_blk;
4037
4038	if ( g_skip_setuid_tests != 0 ) {
4039		printf( "\t skipping this test \n" );
4040		my_err = 0;
4041		goto test_passed_exit;
4042	}
4043
4044	/* start off by checking the status of quotas on the boot volume */
4045	my_err = quotactl( "/System/Library/Kernels/kernel", QCMD(Q_QUOTASTAT, USRQUOTA), 0, (caddr_t)&is_quotas_on );
4046	if ( my_err == -1 ) {
4047		printf( "quotactl - Q_QUOTASTAT - failed with errno %d - %s \n", errno, strerror( errno ) );
4048		goto test_failed_exit;
4049	}
4050
4051	if ( is_quotas_on == 0 ) {
4052		/* quotas are off */
4053		my_err = 0;
4054		goto test_passed_exit;
4055	}
4056
4057	my_err = quotactl( "/System/Library/Kernels/kernel", QCMD(Q_GETQUOTA, USRQUOTA), getuid(), (caddr_t)&my_quota_blk );
4058	if ( my_err == -1 ) {
4059		printf( "quotactl - Q_GETQUOTA - failed with errno %d - %s \n", errno, strerror( errno ) );
4060		goto test_failed_exit;
4061	}
4062
4063	my_err = 0;
4064	goto test_passed_exit;
4065
4066test_failed_exit:
4067	my_err = -1;
4068
4069test_passed_exit:
4070	return( my_err );
4071}
4072
4073/*  **************************************************************************************************************
4074 *	Test getrlimit, setrlimit system calls.
4075 *  **************************************************************************************************************
4076 */
4077int limit_tests( void * the_argp )
4078{
4079	int				my_err;
4080	struct rlimit	my_current_rlimit;
4081	struct rlimit	my_rlimit;
4082
4083 	my_err = getrlimit( RLIMIT_NOFILE, &my_current_rlimit );
4084	if ( my_err == -1 ) {
4085		printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4086		goto test_failed_exit;
4087	}
4088	if ( my_current_rlimit.rlim_cur != RLIM_INFINITY ) {
4089		if ( my_current_rlimit.rlim_cur != my_current_rlimit.rlim_max )
4090			my_current_rlimit.rlim_cur += 1;
4091		else
4092			my_current_rlimit.rlim_cur -= 1;
4093		my_rlimit.rlim_cur = my_current_rlimit.rlim_cur;
4094		my_rlimit.rlim_max = my_current_rlimit.rlim_max;
4095		my_err = setrlimit( RLIMIT_NOFILE, &my_rlimit );
4096		if ( my_err == -1 ) {
4097			printf( "setrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4098			goto test_failed_exit;
4099		}
4100
4101		/* verify that we set a new limit */
4102		bzero( (void *) &my_rlimit, sizeof( my_rlimit ) );
4103		my_err = getrlimit( RLIMIT_NOFILE, &my_rlimit );
4104		if ( my_err == -1 ) {
4105			printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4106			goto test_failed_exit;
4107		}
4108		if ( my_rlimit.rlim_cur != my_current_rlimit.rlim_cur ) {
4109			printf( "failed to get/set new RLIMIT_NOFILE soft limit \n" );
4110			printf( "soft limits - current %lld should be %lld \n", my_rlimit.rlim_cur, my_current_rlimit.rlim_cur );
4111			goto test_failed_exit;
4112		}
4113
4114#if CONFORMANCE_CHANGES_IN_XNU // can't do this check until conformance changes get into xnu
4115		printf( "hard limits - current %lld should be %lld \n", my_rlimit.rlim_max, my_current_rlimit.rlim_max );
4116		if ( my_rlimit.rlim_max != my_current_rlimit.rlim_max ) {
4117			printf( "failed to get/set new RLIMIT_NOFILE hard limit \n" );
4118			goto test_failed_exit;
4119		}
4120#endif
4121
4122		/*
4123		 * A test for a limit that won't fit in a signed 32 bits, a la 5414697
4124		 * Note: my_rlimit should still have a valid rlim_max.
4125		 */
4126		long long biglim = 2147483649ll;	/* Just over 2^31 */
4127		my_rlimit.rlim_cur = biglim;
4128		my_err = setrlimit(RLIMIT_CPU, &my_rlimit);
4129		if (my_err == -1) {
4130			printf("failed to set large limit.\n");
4131			goto test_failed_exit;
4132		}
4133
4134		bzero(&my_rlimit, sizeof(struct rlimit));
4135		my_err = getrlimit(RLIMIT_CPU, &my_rlimit);
4136		if (my_err == -1) {
4137			printf("after setting large value, failed to getrlimit().\n");
4138			goto test_failed_exit;
4139		}
4140
4141		if (my_rlimit.rlim_cur != biglim) {
4142			printf("didn't retrieve large limit.\n");
4143			goto test_failed_exit;
4144		}
4145	}
4146
4147	my_err = 0;
4148	goto test_passed_exit;
4149
4150test_failed_exit:
4151	my_err = -1;
4152
4153test_passed_exit:
4154	return( my_err );
4155}
4156
4157/*  **************************************************************************************************************
4158 *	Test getattrlist, getdirentriesattr, setattrlist system calls.
4159 *  **************************************************************************************************************
4160 */
4161struct test_attr_buf {
4162	uint32_t			length;
4163	fsobj_type_t		obj_type;
4164	fsobj_id_t			obj_id;
4165	struct timespec   	backup_time;
4166};
4167
4168typedef struct test_attr_buf test_attr_buf;
4169
4170int directory_tests( void * the_argp )
4171{
4172	int					my_err, done, found_it, i;
4173	int					my_fd = -1;
4174	int					is_ufs = 0;
4175	char *				my_pathp = NULL;
4176	char *				my_bufp = NULL;
4177	char *				my_file_namep;
4178#ifdef __LP64__
4179	unsigned int		my_base;
4180	unsigned int		my_count;
4181	unsigned int		my_new_state;
4182#else
4183	unsigned long		my_base;
4184	unsigned long		my_count;
4185	unsigned long		my_new_state;
4186#endif
4187	fsobj_id_t			my_obj_id;
4188	struct timespec		my_new_backup_time;
4189	struct attrlist		my_attrlist;
4190	test_attr_buf		my_attr_buf[4];
4191	struct statfs 		my_statfs_buf;
4192	kern_return_t           my_kr;
4193
4194	/* need to know type of file system */
4195	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4196	if ( my_err == -1 ) {
4197		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4198		goto test_failed_exit;
4199	}
4200	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4201		is_ufs = 1;
4202	}
4203
4204        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE);
4205        if(my_kr != KERN_SUCCESS){
4206                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4207                goto test_failed_exit;
4208        }
4209
4210        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4211        if(my_kr != KERN_SUCCESS){
4212                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4213                goto test_failed_exit;
4214        }
4215
4216	*my_pathp = 0x00;
4217	strcat( my_pathp, &g_target_path[0] );
4218	strcat( my_pathp, "/" );
4219
4220	/* create a test file */
4221	my_err = create_random_name( my_pathp, 1 );
4222	if ( my_err != 0 ) {
4223		goto test_failed_exit;
4224	}
4225
4226	/* get pointer to just the file name */
4227	my_file_namep = strrchr( my_pathp, '/' );
4228	my_file_namep++;
4229
4230	/* check out the  test directory */
4231	my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4232	if ( my_fd == -1 ) {
4233		printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4234		goto test_failed_exit;
4235	}
4236
4237	/* test get/setattrlist */
4238	memset( &my_attrlist, 0, sizeof(my_attrlist) );
4239	my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4240	my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4241	my_err = getattrlist( my_pathp, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf[0]), 0 );
4242
4243	if ( my_err != 0 ) {
4244		if ( errno == ENOTSUP && is_ufs ) {
4245			/* getattr calls not supported on ufs */
4246			my_err = 0;
4247			goto test_passed_exit;
4248		}
4249		printf( "getattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4250		goto test_failed_exit;
4251	}
4252	/* validate returned data */
4253	if ( my_attr_buf[0].obj_type != VREG ) {
4254		printf( "getattrlist returned incorrect obj_type data. \n" );
4255		goto test_failed_exit;
4256	}
4257
4258	/* set new backup time */
4259	my_obj_id = my_attr_buf[0].obj_id;
4260	my_new_backup_time = my_attr_buf[0].backup_time;
4261	my_new_backup_time.tv_sec += 60;
4262	my_attr_buf[0].backup_time.tv_sec = my_new_backup_time.tv_sec;
4263	my_attrlist.commonattr = (ATTR_CMN_BKUPTIME);
4264	my_err = setattrlist( my_pathp, &my_attrlist, &my_attr_buf[0].backup_time, sizeof(my_attr_buf[0].backup_time), 0 );
4265	if ( my_err != 0 ) {
4266		printf( "setattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4267		goto test_failed_exit;
4268	}
4269
4270	/* validate setattrlist using getdirentriesattr */
4271	close( my_fd );
4272	my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4273	if ( my_fd == -1 ) {
4274		printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4275		goto test_failed_exit;
4276	}
4277	memset( &my_attrlist, 0, sizeof(my_attrlist) );
4278	memset( &my_attr_buf, 0, sizeof(my_attr_buf) );
4279	my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4280	my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4281	my_count = 4;
4282	my_base = 0;
4283	my_err = getdirentriesattr( my_fd, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf), &my_count,
4284								&my_base, &my_new_state, 0 );
4285	if ( my_err < 0 ) {
4286		printf( "getdirentriesattr call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4287		goto test_failed_exit;
4288	}
4289
4290	found_it = 0;
4291	for ( i = 0; i < my_count; i++ ) {
4292		if ( my_attr_buf[i].obj_id.fid_objno == my_obj_id.fid_objno &&
4293			 my_attr_buf[i].obj_id.fid_generation == my_obj_id.fid_generation ) {
4294			found_it = 1;
4295			if ( my_attr_buf[i].backup_time.tv_sec !=  my_new_backup_time.tv_sec ) {
4296				printf( "setattrlist failed to set backup time. \n" );
4297				goto test_failed_exit;
4298			}
4299		}
4300	}
4301	if ( found_it == 0 ) {
4302		printf( "getdirentriesattr failed to find test file. \n" );
4303		goto test_failed_exit;
4304	}
4305
4306	my_err = 0;
4307	goto test_passed_exit;
4308
4309test_failed_exit:
4310	if(my_err != 0)
4311		my_err = -1;
4312
4313test_passed_exit:
4314	if ( my_fd != -1 )
4315		close( my_fd );
4316	if ( my_pathp != NULL ) {
4317		remove( my_pathp );
4318		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4319	 }
4320	if ( my_bufp != NULL ) {
4321		vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5));
4322	 }
4323	return( my_err );
4324}
4325
4326/*  **************************************************************************************************************
4327 *	Test exchangedata system calls.
4328 *  **************************************************************************************************************
4329 */
4330int exchangedata_test( void * the_argp )
4331{
4332	int				my_err;
4333	int				my_fd1 = -1;
4334	int				my_fd2 = -1;
4335	char *			my_file1_pathp = NULL;
4336	char *			my_file2_pathp = NULL;
4337	ssize_t			my_result;
4338	char			my_buffer[16];
4339	struct statfs	my_statfs_buf;
4340	kern_return_t           my_kr;
4341
4342	/* need to know type of file system */
4343	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4344	if ( my_err == -1 ) {
4345		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4346		goto test_failed_exit;
4347	}
4348	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4349		/* ufs does not support exchangedata */
4350		my_err = 0;
4351		goto test_passed_exit;
4352	}
4353
4354        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file1_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4355        if(my_kr != KERN_SUCCESS){
4356                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4357                goto test_failed_exit;
4358        }
4359
4360	*my_file1_pathp = 0x00;
4361	strcat( my_file1_pathp, &g_target_path[0] );
4362	strcat( my_file1_pathp, "/" );
4363
4364	/* create a test file */
4365	my_err = create_random_name( my_file1_pathp, 1 );
4366	if ( my_err != 0 ) {
4367		printf( "create_random_name my_err: %d\n", my_err );
4368		goto test_failed_exit;
4369	}
4370	my_fd1 = open( my_file1_pathp, O_RDWR, 0 );
4371	if ( my_fd1 == -1 ) {
4372		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4373		goto test_failed_exit;
4374	}
4375	my_result = write( my_fd1, "11111111", 8 );
4376	if ( my_result == -1 ) {
4377		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4378		goto test_failed_exit;
4379	}
4380
4381        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file2_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4382        if(my_kr != KERN_SUCCESS){
4383                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4384                goto test_failed_exit;
4385        }
4386
4387	*my_file2_pathp = 0x00;
4388	strcat( my_file2_pathp, &g_target_path[0] );
4389	strcat( my_file2_pathp, "/" );
4390
4391	/* create a test file */
4392	my_err = create_random_name( my_file2_pathp, 1 );
4393	if ( my_err != 0 ) {
4394		printf( "create_random_name my_err: %d\n", my_err );
4395		goto test_failed_exit;
4396	}
4397	my_fd2 = open( my_file2_pathp, O_RDWR, 0 );
4398	if ( my_fd2 == -1 ) {
4399		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4400		goto test_failed_exit;
4401	}
4402	my_result = write( my_fd2, "22222222", 8 );
4403	if ( my_result == -1 ) {
4404		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4405		goto test_failed_exit;
4406	}
4407	close(my_fd1);
4408	my_fd1 = -1;
4409	close(my_fd2);
4410	my_fd2 = -1;
4411
4412	/* test exchangedata */
4413	my_err = exchangedata( my_file1_pathp, my_file2_pathp, 0 );
4414	if ( my_err == -1 ) {
4415		printf( "exchangedata failed with error %d - \"%s\" \n", errno, strerror( errno) );
4416		goto test_failed_exit;
4417	}
4418
4419	/* now validate exchange */
4420	my_fd1 = open( my_file1_pathp, O_RDONLY, 0 );
4421	if ( my_fd1 == -1 ) {
4422		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4423		goto test_failed_exit;
4424	}
4425	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
4426	my_result = read( my_fd1, &my_buffer[0], 8 );
4427	if ( my_result == -1 ) {
4428		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4429		goto test_failed_exit;
4430	}
4431
4432	if ( memcmp( &my_buffer[0], "22222222", 8 ) != 0 ) {
4433		printf( "exchangedata failed - incorrect data in file \n" );
4434		goto test_failed_exit;
4435	}
4436
4437	my_err = 0;
4438	goto test_passed_exit;
4439
4440test_failed_exit:
4441	my_err = -1;
4442
4443test_passed_exit:
4444	if ( my_fd1 != -1 )
4445		close( my_fd1 );
4446	if ( my_file1_pathp != NULL ) {
4447		remove( my_file1_pathp );
4448		vm_deallocate(mach_task_self(), (vm_address_t)my_file1_pathp, PATH_MAX);
4449	 }
4450	if ( my_fd2 != -1 )
4451		close( my_fd2 );
4452	if ( my_file2_pathp != NULL ) {
4453		remove( my_file2_pathp );
4454		vm_deallocate(mach_task_self(), (vm_address_t)my_file2_pathp, PATH_MAX);
4455	 }
4456	return( my_err );
4457}
4458
4459
4460/*  **************************************************************************************************************
4461 *	Test searchfs system calls.
4462 *  **************************************************************************************************************
4463 */
4464
4465struct packed_name_attr {
4466    u_int32_t	            size;	/* Of the remaining fields */
4467    struct attrreference	ref;	/* Offset/length of name itself */
4468    char 			        name[  PATH_MAX ];
4469};
4470
4471struct packed_attr_ref {
4472    u_int32_t    		    size;	/* Of the remaining fields */
4473    struct attrreference	ref;	/* Offset/length of attr itself */
4474};
4475
4476struct packed_result {
4477    u_int32_t	        size;		/* Including size field itself */
4478    attrreference_t     obj_name;
4479    struct fsobj_id	    obj_id;
4480    struct timespec     obj_create_time;
4481    char                room_for_name[ 64 ];
4482};
4483typedef struct packed_result packed_result;
4484typedef struct packed_result * packed_result_p;
4485
4486#define MAX_MATCHES	10
4487#define MAX_EBUSY_RETRIES 20
4488
4489int searchfs_test( void * the_argp )
4490{
4491	int						my_err, my_items_found = 0, my_ebusy_count;
4492	char *					my_pathp = NULL;
4493    unsigned long			my_matches;
4494    unsigned long			my_search_options;
4495    struct fssearchblock	my_search_blk;
4496    struct attrlist			my_return_list;
4497    struct searchstate		my_search_state;
4498    struct packed_name_attr	my_info1;
4499    struct packed_attr_ref	my_info2;
4500    packed_result			my_result_buffer[ MAX_MATCHES ];
4501	struct statfs			my_statfs_buf;
4502	kern_return_t           my_kr;
4503
4504	/* need to know type of file system */
4505	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4506	if ( my_err == -1 ) {
4507		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4508		goto test_failed_exit;
4509	}
4510	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4511		/* ufs does not support exchangedata */
4512		my_err = 0;
4513		goto test_passed_exit;
4514	}
4515
4516        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4517        if(my_kr != KERN_SUCCESS){
4518                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4519                goto test_failed_exit;
4520        }
4521
4522	*my_pathp = 0x00;
4523	strcat( my_pathp, &g_target_path[0] );
4524	strcat( my_pathp, "/" );
4525
4526	/* create test files */
4527	my_err = create_file_with_name( my_pathp, "foo", 0 );
4528	if ( my_err < 0 ) {
4529		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4530		goto test_failed_exit;
4531	}
4532
4533	my_err = create_file_with_name( my_pathp, "foobar", 0 );
4534	if ( my_err < 0 ) {
4535		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4536		goto test_failed_exit;
4537	}
4538
4539	my_err = create_file_with_name( my_pathp, "foofoo", 0 );
4540	if ( my_err < 0 ) {
4541		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4542		goto test_failed_exit;
4543	}
4544
4545	my_err = create_file_with_name( my_pathp, "xxxfoo", 0 );
4546	if ( my_err < 0 ) {
4547		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4548		goto test_failed_exit;
4549	}
4550
4551    /* EBUSY count  updated below the catalogue_changed label */
4552    my_ebusy_count = 0;
4553
4554catalogue_changed:
4555	/* search target volume for all file system objects with "foo" in the name */
4556    /* Set up the attributes we're searching on. */
4557    my_items_found = 0; /* Set this here in case we're completely restarting */
4558    my_search_blk.searchattrs.bitmapcount = ATTR_BIT_MAP_COUNT;
4559    my_search_blk.searchattrs.reserved = 0;
4560    my_search_blk.searchattrs.commonattr = ATTR_CMN_NAME;
4561    my_search_blk.searchattrs.volattr = 0;
4562    my_search_blk.searchattrs.dirattr = 0;
4563    my_search_blk.searchattrs.fileattr = 0;
4564    my_search_blk.searchattrs.forkattr = 0;
4565
4566    /* Set up the attributes we want for all returned matches. */
4567    /* Why is returnattrs a pointer instead of an embedded struct? */
4568    my_search_blk.returnattrs = &my_return_list;
4569    my_return_list.bitmapcount = ATTR_BIT_MAP_COUNT;
4570    my_return_list.reserved = 0;
4571    my_return_list.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJID | ATTR_CMN_CRTIME;
4572    my_return_list.volattr = 0;
4573    my_return_list.dirattr = 0;
4574    my_return_list.fileattr = 0;
4575    my_return_list.forkattr = 0;
4576
4577    /* Allocate a buffer for returned matches */
4578    my_search_blk.returnbuffer = my_result_buffer;
4579    my_search_blk.returnbuffersize = sizeof(my_result_buffer);
4580
4581    /* Pack the searchparams1 into a buffer */
4582    /* NOTE: A name appears only in searchparams1 */
4583    strcpy( my_info1.name, "foo" );
4584    my_info1.ref.attr_dataoffset = sizeof(struct attrreference);
4585    my_info1.ref.attr_length = strlen(my_info1.name) + 1;
4586    my_info1.size = sizeof(struct attrreference) + my_info1.ref.attr_length;
4587    my_search_blk.searchparams1 = &my_info1;
4588    my_search_blk.sizeofsearchparams1 = my_info1.size + sizeof(u_int32_t);
4589
4590    /* Pack the searchparams2 into a buffer */
4591    my_info2.size = sizeof(struct attrreference);
4592    my_info2.ref.attr_dataoffset = sizeof(struct attrreference);
4593    my_info2.ref.attr_length = 0;
4594    my_search_blk.searchparams2 = &my_info2;
4595    my_search_blk.sizeofsearchparams2 = sizeof(my_info2);
4596
4597    /* Maximum number of matches we want */
4598    my_search_blk.maxmatches = MAX_MATCHES;
4599
4600    /* Maximum time to search, per call */
4601    my_search_blk.timelimit.tv_sec = 1;
4602    my_search_blk.timelimit.tv_usec = 0;
4603
4604    my_search_options = (SRCHFS_START | SRCHFS_MATCHPARTIALNAMES |
4605						 SRCHFS_MATCHFILES | SRCHFS_MATCHDIRS);
4606	do {
4607		char *  my_end_ptr;
4608		char *	my_ptr;
4609		int		i;
4610
4611		my_err = searchfs( my_pathp, &my_search_blk, &my_matches, 0, my_search_options, &my_search_state );
4612        if ( my_err == -1 )
4613            my_err = errno;
4614        if ( (my_err == 0 || my_err == EAGAIN) && my_matches > 0 ) {
4615            /* Unpack the results */
4616          //  printf("my_matches %d \n", my_matches);
4617            my_ptr = (char *) &my_result_buffer[0];
4618            my_end_ptr = (my_ptr + sizeof(my_result_buffer));
4619            for ( i = 0; i < my_matches; ++i ) {
4620                packed_result_p		my_result_p = (packed_result_p) my_ptr;
4621				char *				my_name_p;
4622
4623				/* see if we foound all our test files */
4624				my_name_p = (((char *)(&my_result_p->obj_name)) + my_result_p->obj_name.attr_dataoffset);
4625				if ( memcmp( my_name_p, "foo", 3 ) == 0 ||
4626					 memcmp( my_name_p, "foobar", 6 ) == 0 ||
4627					 memcmp( my_name_p, "foofoo", 6 ) == 0 ||
4628					 memcmp( my_name_p, "xxxfoo", 6 ) == 0 ) {
4629					my_items_found++;
4630				}
4631#if DEBUG
4632                printf("obj_name \"%.*s\" \n",
4633                    (int) my_result_p->obj_name.attr_length,
4634                    (((char *)(&my_result_p->obj_name)) +
4635                     my_result_p->obj_name.attr_dataoffset));
4636                printf("size %d fid_objno %d fid_generation %d tv_sec 0x%02LX \n",
4637                    my_result_p->size, my_result_p->obj_id.fid_objno,
4638                    my_result_p->obj_id.fid_generation,
4639                    my_result_p->obj_create_time.tv_sec);
4640#endif
4641                my_ptr = (my_ptr + my_result_p->size);
4642                if (my_ptr > my_end_ptr)
4643                    break;
4644            }
4645        }
4646
4647	/* EBUSY indicates catalogue change; retry a few times. */
4648	if ((my_err == EBUSY) && (my_ebusy_count++ < MAX_EBUSY_RETRIES)) {
4649		goto catalogue_changed;
4650	}
4651	if ( !(my_err == 0 || my_err == EAGAIN) ) {
4652		printf( "searchfs failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4653	}
4654	my_search_options &= ~SRCHFS_START;
4655    } while ( my_err == EAGAIN );
4656
4657	if ( my_items_found < 4 ) {
4658		printf( "searchfs failed to find all test files \n" );
4659		goto test_failed_exit;
4660	}
4661
4662	my_err = 0;
4663	goto test_passed_exit;
4664
4665test_failed_exit:
4666	my_err = -1;
4667
4668test_passed_exit:
4669	if ( my_pathp != NULL ) {
4670		char *   my_ptr = (my_pathp + strlen( my_pathp ));
4671		strcat( my_pathp, "foo" );
4672		remove( my_pathp );
4673		*my_ptr = 0x00;
4674		strcat( my_pathp, "foobar" );
4675		remove( my_pathp );
4676		*my_ptr = 0x00;
4677		strcat( my_pathp, "foofoo" );
4678		remove( my_pathp );
4679		*my_ptr = 0x00;
4680		strcat( my_pathp, "xxxfoo" );
4681		remove( my_pathp );
4682		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4683	 }
4684	return( my_err );
4685}
4686
4687
4688#define  AIO_TESTS_BUFFER_SIZE  (1024 * 4000)
4689#define  AIO_TESTS_OUR_COUNT  5
4690/*  **************************************************************************************************************
4691 *	Test aio_error, aio_read, aio_return, aio_suspend, aio_write, fcntl system calls.
4692 *  **************************************************************************************************************
4693 */
4694int aio_tests( void * the_argp )
4695{
4696	int					my_err, i;
4697	char *				my_pathp;
4698	struct aiocb *		my_aiocbp;
4699	ssize_t				my_result;
4700	struct timespec		my_timeout;
4701	int					my_fd_list[ AIO_TESTS_OUR_COUNT ];
4702	char *				my_buffers[ AIO_TESTS_OUR_COUNT ];
4703	struct aiocb *		my_aiocb_list[ AIO_TESTS_OUR_COUNT ];
4704	struct aiocb		my_aiocbs[ AIO_TESTS_OUR_COUNT ];
4705	char *				my_file_paths[ AIO_TESTS_OUR_COUNT ];
4706	kern_return_t           my_kr;
4707
4708	/* set up to have the ability to fire off up to AIO_TESTS_OUR_COUNT async IOs at once */
4709	memset( &my_fd_list[0], 0xFF, sizeof( my_fd_list ) );
4710	memset( &my_buffers[0], 0x00, sizeof( my_buffers ) );
4711	memset( &my_aiocb_list[0], 0x00, sizeof( my_aiocb_list ) );
4712	memset( &my_file_paths[0], 0x00, sizeof( my_file_paths ) );
4713	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4714	    	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_buffers[ i ], AIO_TESTS_BUFFER_SIZE, VM_FLAGS_ANYWHERE);
4715		if(my_kr != KERN_SUCCESS){
4716                	printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4717                	goto test_failed_exit;
4718       		}
4719
4720	        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file_paths[ i ], PATH_MAX, VM_FLAGS_ANYWHERE);
4721                if(my_kr != KERN_SUCCESS){
4722                        printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4723                        goto test_failed_exit;
4724                }
4725
4726		my_pathp = my_file_paths[ i ];
4727		*my_pathp = 0x00;
4728		strcat( my_pathp, &g_target_path[0] );
4729		strcat( my_pathp, "/" );
4730
4731		/* create a test file */
4732		my_err = create_random_name( my_pathp, 1 );
4733		if ( my_err != 0 ) {
4734			goto test_failed_exit;
4735		}
4736		my_fd_list[ i ] = open( my_pathp, O_RDWR, 0 );
4737		if ( my_fd_list[ i ] <= 0 ) {
4738			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4739			goto test_failed_exit;
4740		}
4741
4742		my_aiocbp = &my_aiocbs[ i ];
4743		my_aiocb_list[ i ] = my_aiocbp;
4744		memset( my_aiocbp, 0x00, sizeof( *my_aiocbp ) );
4745		my_aiocbp->aio_fildes = my_fd_list[ i ];
4746		my_aiocbp->aio_buf = (char *) my_buffers[ i ];
4747		my_aiocbp->aio_nbytes = 1024;
4748		my_aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; // no signals at completion;
4749		my_aiocbp->aio_sigevent.sigev_signo = 0;
4750	}
4751
4752	/* test direct IO (F_NOCACHE) and aio_write */
4753	my_err = fcntl( my_fd_list[ 0 ], F_NOCACHE, 1 );
4754	if ( my_err != 0 ) {
4755		printf( "malloc failed with error %d - \"%s\" \n", errno, strerror( errno) );
4756		goto test_failed_exit;
4757	}
4758
4759	my_aiocbp = &my_aiocbs[ 0 ];
4760    my_aiocbp->aio_fildes = my_fd_list[ 0 ];
4761	my_aiocbp->aio_offset = 4096;
4762	my_aiocbp->aio_buf = my_buffers[ 0 ];
4763    my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE;
4764    my_aiocbp->aio_reqprio = 0;
4765    my_aiocbp->aio_sigevent.sigev_notify = 0;
4766    my_aiocbp->aio_sigevent.sigev_signo = 0;
4767    my_aiocbp->aio_sigevent.sigev_value.sival_int = 0;
4768    my_aiocbp->aio_sigevent.sigev_notify_function = NULL;
4769    my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL;
4770    my_aiocbp->aio_lio_opcode = 0;
4771
4772	/* write some data */
4773	memset( my_buffers[ 0 ], 'j', AIO_TESTS_BUFFER_SIZE );
4774    my_err = aio_write( my_aiocbp );
4775	if ( my_err != 0 ) {
4776		printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4777		goto test_failed_exit;
4778	}
4779
4780    while ( 1 ) {
4781        my_err = aio_error( my_aiocbp );
4782        if ( my_err == EINPROGRESS ) {
4783            /* wait for IO to complete */
4784            sleep( 1 );
4785            continue;
4786        }
4787        else if ( my_err == 0 ) {
4788            ssize_t		my_result;
4789            my_result = aio_return( my_aiocbp );
4790            break;
4791        }
4792        else {
4793			printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4794			goto test_failed_exit;
4795        }
4796    } /* while loop */
4797
4798	/* read some data */
4799	memset( my_buffers[ 0 ], 'x', AIO_TESTS_BUFFER_SIZE );
4800    my_err = aio_read( my_aiocbp );
4801
4802    while ( 1 ) {
4803        my_err = aio_error( my_aiocbp );
4804        if ( my_err == EINPROGRESS ) {
4805            /* wait for IO to complete */
4806            sleep( 1 );
4807            continue;
4808        }
4809        else if ( my_err == 0 ) {
4810            ssize_t		my_result;
4811            my_result = aio_return( my_aiocbp );
4812
4813			if ( *(my_buffers[ 0 ]) != 'j' || *(my_buffers[ 0 ] + AIO_TESTS_BUFFER_SIZE - 1) != 'j' ) {
4814				printf( "aio_read or aio_write failed - wrong data read \n" );
4815				goto test_failed_exit;
4816			}
4817            break;
4818        }
4819        else {
4820			printf( "aio_read failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4821			goto test_failed_exit;
4822        }
4823    } /* while loop */
4824
4825	/* test aio_fsync */
4826	close( my_fd_list[ 0 ] );
4827	my_fd_list[ 0 ] = open( my_pathp, O_RDWR, 0 );
4828	if ( my_fd_list[ 0 ] == -1 ) {
4829		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4830		goto test_failed_exit;
4831	}
4832
4833	my_aiocbp = &my_aiocbs[ 0 ];
4834    my_aiocbp->aio_fildes = my_fd_list[ 0 ];
4835    my_aiocbp->aio_offset = 0;
4836    my_aiocbp->aio_buf = my_buffers[ 0 ];
4837    my_aiocbp->aio_nbytes = 1024;
4838    my_aiocbp->aio_reqprio = 0;
4839    my_aiocbp->aio_sigevent.sigev_notify = 0;
4840    my_aiocbp->aio_sigevent.sigev_signo = 0;
4841    my_aiocbp->aio_sigevent.sigev_value.sival_int = 0;
4842    my_aiocbp->aio_sigevent.sigev_notify_function = NULL;
4843    my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL;
4844    my_aiocbp->aio_lio_opcode = 0;
4845
4846	/* write some data */
4847	memset( my_buffers[ 0 ], 'e', 1024 );
4848    my_err = aio_write( my_aiocbp );
4849	if ( my_err != 0 ) {
4850		printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4851		goto test_failed_exit;
4852	}
4853    while ( 1 ) {
4854        my_err = aio_error( my_aiocbp );
4855        if ( my_err == EINPROGRESS ) {
4856            /* wait for IO to complete */
4857            sleep( 1 );
4858            continue;
4859        }
4860        else if ( my_err == 0 ) {
4861            ssize_t		my_result;
4862            my_result = aio_return( my_aiocbp );
4863            break;
4864        }
4865        else {
4866			printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4867			goto test_failed_exit;
4868        }
4869    } /* while loop */
4870
4871	my_err = aio_fsync( O_SYNC, my_aiocbp );
4872	if ( my_err != 0 ) {
4873		printf( "aio_fsync failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4874		goto test_failed_exit;
4875	}
4876    while ( 1 ) {
4877        my_err = aio_error( my_aiocbp );
4878        if ( my_err == EINPROGRESS ) {
4879            /* wait for IO to complete */
4880            sleep( 1 );
4881            continue;
4882        }
4883        else if ( my_err == 0 ) {
4884			aio_return( my_aiocbp );
4885            break;
4886        }
4887        else {
4888			printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4889			goto test_failed_exit;
4890        }
4891    } /* while loop */
4892
4893	/* validate write */
4894	memset( my_buffers[ 0 ], 0x20, 16 );
4895	lseek( my_fd_list[ 0 ], 0, SEEK_SET );
4896	my_result = read( my_fd_list[ 0 ], my_buffers[ 0 ], 16);
4897	if ( my_result == -1 ) {
4898		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4899		goto test_failed_exit;
4900	}
4901	if ( *(my_buffers[ 0 ]) != 'e' || *(my_buffers[ 0 ] + 16 - 1) != 'e' ) {
4902		printf( "aio_fsync or aio_write failed - wrong data read \n" );
4903		goto test_failed_exit;
4904	}
4905
4906	/* test aio_suspend and lio_listio */
4907	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4908		memset( my_buffers[ i ], 'a', AIO_TESTS_BUFFER_SIZE );
4909		my_aiocbp = &my_aiocbs[ i ];
4910		my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE;
4911		my_aiocbp->aio_lio_opcode = LIO_WRITE;
4912	}
4913    my_err = lio_listio( LIO_NOWAIT, my_aiocb_list, AIO_TESTS_OUR_COUNT, NULL );
4914	if ( my_err != 0 ) {
4915		printf( "lio_listio call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4916		goto test_failed_exit;
4917	}
4918
4919	my_timeout.tv_sec = 1;
4920	my_timeout.tv_nsec = 0;
4921	my_err = aio_suspend( (const struct aiocb *const*) my_aiocb_list, AIO_TESTS_OUR_COUNT, &my_timeout );
4922	if ( my_err != 0 ) {
4923		printf( "aio_suspend call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4924		goto test_failed_exit;
4925	}
4926
4927	/* test aio_cancel */
4928	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4929		my_aiocbp = &my_aiocbs[ i ];
4930		my_err = aio_cancel( my_aiocbp->aio_fildes, my_aiocbp );
4931		if ( my_err != AIO_ALLDONE && my_err != AIO_CANCELED && my_err != AIO_NOTCANCELED ) {
4932			printf( "aio_cancel failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4933			goto test_failed_exit;
4934		}
4935	}
4936
4937	my_err = 0;
4938	goto test_passed_exit;
4939
4940test_failed_exit:
4941	my_err = -1;
4942
4943test_passed_exit:
4944	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4945		if ( my_fd_list[ i ] != -1 ) {
4946			close( my_fd_list[ i ] );
4947			my_fd_list[ i ] = -1;
4948		}
4949		if ( my_file_paths[ i ] != NULL ) {
4950			remove( my_file_paths[ i ] );
4951			vm_deallocate(mach_task_self(), (vm_address_t)my_file_paths[ i ], PATH_MAX);
4952			my_file_paths[ i ] = NULL;
4953		}
4954		if ( my_buffers[ i ] != NULL ) {
4955			vm_deallocate(mach_task_self(), (vm_address_t)my_buffers[ i ], AIO_TESTS_BUFFER_SIZE);
4956			my_buffers[ i ] = NULL;
4957		}
4958	}
4959	return( my_err );
4960}
4961
4962
4963/*  **************************************************************************************************************
4964 *	Test msgctl, msgget, msgrcv, msgsnd system calls.
4965 *  **************************************************************************************************************
4966 */
4967int message_queue_tests( void * the_argp )
4968{
4969	int					my_err;
4970	int					my_msg_queue_id = -1;
4971	ssize_t				my_result;
4972	struct msqid_ds		my_msq_ds;
4973	struct testing_msq_message {
4974		long	msq_type;
4975		char	msq_buffer[ 32 ];
4976	}					my_msg;
4977
4978	/* get a message queue established for our use */
4979	my_msg_queue_id = msgget( IPC_PRIVATE, (IPC_CREAT | IPC_EXCL | IPC_R | IPC_W) );
4980	if ( my_msg_queue_id == -1 ) {
4981		printf( "msgget failed with errno %d - %s \n", errno, strerror( errno ) );
4982		goto test_failed_exit;
4983	}
4984
4985	/* get some stats on our message queue */
4986	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
4987	if ( my_err == -1 ) {
4988		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
4989		goto test_failed_exit;
4990	}
4991	if ( my_msq_ds.msg_perm.cuid != geteuid( ) ) {
4992		printf( "msgctl IPC_STAT failed to get correct creator uid \n" );
4993		goto test_failed_exit;
4994	}
4995	if ( (my_msq_ds.msg_perm.mode & (IPC_R | IPC_W)) == 0 ) {
4996		printf( "msgctl IPC_STAT failed to get correct mode \n" );
4997		goto test_failed_exit;
4998	}
4999
5000	/* put a message into our queue */
5001	my_msg.msq_type = 1;
5002	strcpy( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" );
5003	my_err = msgsnd( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0 );
5004	if ( my_err == -1 ) {
5005		printf( "msgsnd failed with errno %d - %s \n", errno, strerror( errno ) );
5006		goto test_failed_exit;
5007	}
5008
5009	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
5010	if ( my_err == -1 ) {
5011		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
5012		goto test_failed_exit;
5013	}
5014	if ( my_msq_ds.msg_qnum != 1 ) {
5015		printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5016		goto test_failed_exit;
5017	}
5018
5019	/* pull message off the queue */
5020	bzero( (void *)&my_msg, sizeof( my_msg ) );
5021	my_result = msgrcv( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0, 0 );
5022	if ( my_result == -1 ) {
5023		printf( "msgrcv failed with errno %d - %s \n", errno, strerror( errno ) );
5024		goto test_failed_exit;
5025	}
5026	if ( my_result != sizeof( my_msg.msq_buffer ) ) {
5027		printf( "msgrcv failed to return the correct number of bytes in our buffer \n" );
5028		goto test_failed_exit;
5029	}
5030	if ( strcmp( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ) != 0 ) {
5031		printf( "msgrcv failed to get the correct message \n" );
5032		goto test_failed_exit;
5033	}
5034
5035	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
5036	if ( my_err == -1 ) {
5037		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
5038		goto test_failed_exit;
5039	}
5040	if ( my_msq_ds.msg_qnum != 0 ) {
5041		printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5042		goto test_failed_exit;
5043	}
5044
5045	/* tear down the message queue */
5046	my_err = msgctl( my_msg_queue_id, IPC_RMID, NULL );
5047	if ( my_err == -1 ) {
5048		printf( "msgctl IPC_RMID failed with errno %d - %s \n", errno, strerror( errno ) );
5049		goto test_failed_exit;
5050	}
5051	my_msg_queue_id = -1;
5052
5053	my_err = 0;
5054	goto test_passed_exit;
5055
5056test_failed_exit:
5057	my_err = -1;
5058
5059test_passed_exit:
5060	if ( my_msg_queue_id != -1 ) {
5061		msgctl( my_msg_queue_id, IPC_RMID, NULL );
5062	}
5063	return( my_err );
5064}
5065
5066
5067
5068/*  **************************************************************************************************************
5069 *	Test execution from data and stack areas.
5070 *  **************************************************************************************************************
5071 */
5072int data_exec_tests( void * the_argp )
5073{
5074	int my_err = 0;
5075	int arch, bits;
5076	posix_spawnattr_t attrp;
5077	char *argv[] = { "helpers/data_exec32nonxspawn", NULL };
5078
5079	int my_pid, my_status, ret;
5080
5081	if ((arch = get_architecture()) == -1) {
5082		printf("data_exec_test: couldn't determine architecture\n");
5083		goto test_failed_exit;
5084	}
5085
5086	bits = get_bits();
5087
5088	/*
5089	 * If the machine is 64-bit capable, run both the 32 and 64 bit versions of the test.
5090	 * Otherwise, just run the 32-bit version.
5091	 */
5092
5093	if (arch == INTEL) {
5094		if (bits == 64) {
5095			if (system("arch -arch x86_64 helpers/data_exec") != 0) {
5096				printf("data_exec-x86_64 failed\n");
5097				goto test_failed_exit;
5098			}
5099		}
5100
5101		if (system("arch -arch i386 helpers/data_exec") != 0) {
5102			printf("data_exec-i386 failed\n");
5103			goto test_failed_exit;
5104		}
5105
5106		posix_spawnattr_init(&attrp);
5107		posix_spawnattr_setflags(&attrp, _POSIX_SPAWN_ALLOW_DATA_EXEC );
5108		ret = posix_spawn(&my_pid, "helpers/data_exec32nonxspawn", NULL, &attrp, argv, NULL);
5109		if (ret) {
5110			printf("data_exec-i386 failed in posix_spawn %s\n", strerror(errno));
5111			goto test_failed_exit;
5112		}
5113		ret = wait4(my_pid, &my_status, 0, NULL);
5114		if (ret == -1) {
5115			printf("data_exec-i386 wait4 failed with errno %d - %s\n", errno, strerror(errno));
5116			goto test_failed_exit;
5117		}
5118		if (WEXITSTATUS(my_status) != 0) {
5119			printf("data_exec-i386 _POSIX_SPAWN_ALLOW_DATA_EXEC failed\n");
5120			goto test_failed_exit;
5121		}
5122	}
5123
5124	/* Add new architectures here similar to the above. */
5125
5126	goto test_passed_exit;
5127
5128test_failed_exit:
5129	my_err = -1;
5130
5131test_passed_exit:
5132	return my_err;
5133}
5134
5135/*  **************************************************************************************************************
5136 *	Test KASLR-related functionality
5137 *  **************************************************************************************************************
5138 */
5139int kaslr_test( void * the_argp )
5140{
5141	int result = 0;
5142	uint64_t slide = 0;
5143	size_t size;
5144	int slide_enabled;
5145
5146	size = sizeof(slide_enabled);
5147	result = sysctlbyname("kern.slide", &slide_enabled, &size, NULL, 0);
5148	if (result != 0) {
5149		printf("sysctlbyname(\"kern.slide\") failed with errno %d\n", errno);
5150		goto test_failed_exit;
5151	}
5152
5153	/* Test positive case first */
5154	size = sizeof(slide);
5155	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size);
5156	if (result == 0) {
5157		/* syscall supported, slide must be non-zero if running latest xnu and KASLR is enabled */
5158		if (slide_enabled && (slide == 0)) {
5159			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported slide of 0x%016llx\n", slide);
5160			goto test_failed_exit;
5161		}
5162		if (size != sizeof(slide)) {
5163			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported size of %lu\n", size);
5164			goto test_failed_exit;
5165		}
5166	} else {
5167		/* Only ENOTSUP is allowed. If so, assume all calls will be unsupported */
5168		if (errno == ENOTSUP) {
5169			return 0;
5170		} else {
5171			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) returned unexpected errno (errno %d)\n", errno);
5172			goto test_failed_exit;
5173		}
5174	}
5175
5176	/* Negative cases for expected failures */
5177	size = sizeof(slide);
5178	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, &size);
5179	if ((result == 0) || (errno != EFAULT)) {
5180		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5181		goto test_failed_exit;
5182	}
5183
5184	size = sizeof(slide) + 1; /* EINVAL */
5185	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size);
5186	if ((result == 0) || (errno != EINVAL)) {
5187		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size+1) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5188		goto test_failed_exit;
5189	}
5190
5191	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, NULL /* EFAULT */);
5192	if ((result == 0) || (errno != EFAULT)) {
5193		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, NULL) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5194		goto test_failed_exit;
5195	}
5196
5197	size = sizeof(slide);
5198	result = kas_info(KAS_INFO_MAX_SELECTOR /* EINVAL */, &slide, &size);
5199	if ((result == 0) || (errno != EINVAL)) {
5200		printf("kas_info(KAS_INFO_MAX_SELECTOR, &slide, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5201		goto test_failed_exit;
5202	}
5203
5204	return 0;
5205
5206test_failed_exit:
5207	return -1;
5208}
5209
5210typedef struct attrs {
5211         uint32_t          attrs_length;
5212         attribute_set_t   attrs_returned;
5213         uint32_t          attr_error;
5214         attrreference_t   attr_name;
5215         fsobj_type_t      attr_obj_type;
5216
5217         union {
5218         	struct {
5219         		uint32_t entry_count;
5220         	} directory;
5221         	struct {
5222         		off_t	size;
5223         	} file;
5224         } attr_obj;
5225
5226} attrs_t;
5227
5228int getattrlistbulk_test( void * the_argp )
5229{
5230
5231	int 	error;
5232	struct attrlist attr_list;
5233	attrs_t *attrsptr;
5234	char 	*entry_start;
5235	int 	retcount = 0, totalcount = 0;
5236	int	index;
5237	char	*nameptr;
5238	int 	attr_buf_size;
5239	char	*attr_buf;
5240	int 	dirfd = -1;
5241	char* 	target = "/System/Library/CoreServices";
5242
5243	memset(&attr_list, 0, sizeof(attr_list));
5244	attr_list.bitmapcount = ATTR_BIT_MAP_COUNT;
5245	attr_list.commonattr  = ATTR_CMN_RETURNED_ATTRS |
5246			ATTR_CMN_NAME |
5247			ATTR_CMN_OBJTYPE |
5248			ATTR_CMN_ERROR |
5249			ATTR_FILE_TOTALSIZE|
5250			ATTR_DIR_ENTRYCOUNT;
5251
5252	error = 0;
5253	/*allocate a buffer for 10 items*/
5254	attr_buf_size = 10 * (sizeof(attrs_t) + FILENAME_MAX );
5255	if (vm_allocate((vm_map_t) mach_task_self(),
5256		(vm_address_t*)&attr_buf,
5257		attr_buf_size, VM_FLAGS_ANYWHERE) != KERN_SUCCESS) {
5258		printf( "vm_allocate failed with error %d - \"%s\" \n",
5259			errno, strerror( errno) );
5260		attr_buf = NULL;
5261		error = -1;
5262		goto last_exit;
5263	}
5264
5265	dirfd = openat (AT_FDCWD, target, O_RDONLY, 0);
5266	if (dirfd == -1) {
5267		printf("openat \"%s\" failed with  error %d - \"%s\" \n",
5268			target, errno, strerror( errno));
5269		error = -1;
5270		goto last_exit;
5271	}
5272
5273	do {
5274	 	retcount = getattrlistbulk(dirfd,
5275				&attr_list, &attr_buf[0],
5276				attr_buf_size, FSOPT_PACK_INVAL_ATTRS);
5277		 if (retcount == -1) {
5278			printf("getattrlistbulk on %s returned %d items\n",
5279				target, totalcount);
5280		 	printf("getattrlistbulk failed with  error %d - \"%s\" \n",
5281             			errno, strerror( errno));
5282             		error = -1;
5283             		break;
5284		 } else if (retcount == 0) {
5285		 	/* No more entries in directory */
5286		 	printf("getattrlistbulk succeded: found %d entries in %s\n", totalcount, target);
5287		 	error = 0;
5288		    	break;
5289		 } else {
5290		 	totalcount += retcount;
5291		     	entry_start = &attr_buf[0];
5292			for (index = 0; index < retcount; index++) {
5293				/*set attrsptr to item record buffer*/
5294				attrsptr = (attrs_t *)entry_start;
5295
5296				/*
5297				 *calculate starting point for next item in bulk
5298				 *list
5299				 */
5300				entry_start += attrsptr->attrs_length;
5301
5302				if ((attrsptr->attrs_returned.commonattr & ATTR_CMN_ERROR) &&
5303				     attrsptr->attr_error) {
5304					nameptr = (char*)(&(attrsptr->attr_name)) + attrsptr->attr_name.attr_dataoffset;
5305					printf("getattrlistbulk item \"%s\" ATTR_CMN_ERROR %d \"%s\"\n",
5306						nameptr, attrsptr->attr_error,
5307						strerror(attrsptr->attr_error));
5308				}
5309			}
5310		}
5311	} while (1);
5312
5313last_exit:
5314	if (dirfd != -1) {
5315		(void)close(dirfd);
5316	}
5317
5318	if (attr_buf != NULL) {
5319		vm_deallocate(
5320			mach_task_self(), (vm_address_t)attr_buf, attr_buf_size);
5321	}
5322
5323	return error;
5324}
5325
5326#define INVALID_FD -173
5327static int create_random_name_at(int the_dirfd, char *the_dirpathp,
5328			char *the_namep, size_t the_namep_len,
5329			char *the_pathp, size_t the_pathp_len,
5330			int do_create );
5331/*
5332 * create_random_name_at - creates a file with a random / unique name in the given directory.
5333 * when do_create is true we create a file else we generaate a name that does not exist in the
5334 * given directory (we do not create anything when do_open is 0).
5335 * A name is generated relative to the directory fd. If both a directory path and
5336 * and a buffer to hold the full pathname are provided, an abolute pathname is also returned.
5337 * An absolute pathname for the generated filename is returned in my_pathp.
5338 * WARNING - caller provides enough space in the_namep buffer for longest possible name (NAME_MAX).
5339 * WARNING - caller provides enough space in the_pathp buffer for longest possible path (PATH_MAX).
5340 * RAND_MAX is currently 2147483647 (ten characters plus one for a slash)
5341 */
5342int create_random_name_at(int the_dirfd, char *the_dirpathp,
5343			char *the_namep, size_t the_namep_len,
5344			char *the_pathp, size_t the_pathp_len,
5345			int do_create )
5346{
5347	int		i, my_err;
5348	int		my_fd = -1;
5349
5350	for ( i = 0; i < 1; i++ ) {
5351		int		my_rand;
5352		char		*myp;
5353		char		my_name[32];
5354
5355		my_rand = rand( );
5356		sprintf( &my_name[0], "%d", my_rand );
5357		if ( (strlen( &my_name[0] ) + strlen( the_dirpathp ) + 2) > PATH_MAX ) {
5358			printf( "%s - path to test file greater than PATH_MAX \n", __FUNCTION__ );
5359			return( -1 );
5360		}
5361
5362		// generate name and absolute path
5363		myp = the_namep;
5364		*(myp) = (char)0x00;
5365		strlcat(the_namep, &my_name[0], the_namep_len);
5366
5367		/*
5368		 *If the caller has passed in a path pointer and directory path
5369		 *it means an absolute path is to be returned as well.
5370		 */
5371		if (the_pathp && the_dirpathp) {
5372			*the_pathp = (char)0x00;
5373			strlcat(the_pathp, the_dirpathp, the_pathp_len);
5374			strlcat(the_pathp, "/", the_pathp_len);
5375			strlcat(the_pathp, the_namep, the_pathp_len);
5376		}
5377
5378		if (do_create) {
5379			/* create a file with this name */
5380			my_fd = openat( the_dirfd, the_namep, (O_RDWR | O_CREAT | O_EXCL),
5381				     (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
5382			if ( my_fd == -1 ) {
5383				if ( errno != EEXIST ) {
5384					printf( "%s - open failed with errno %d - %s \n",
5385					       __FUNCTION__, errno, strerror( errno ) );
5386					return( -1 );
5387				}
5388				// name already exists, try another
5389				i--;
5390				continue;
5391			}
5392		}
5393
5394		else {
5395			/* make sure the name is unique */
5396			struct stat		my_sb;
5397			my_err = fstatat( the_dirfd, the_namep, &my_sb, 0 );
5398			if ( my_err != 0 ) {
5399				if ( errno == ENOENT ) {
5400					break;
5401				}
5402				else {
5403					printf( "%s - open failed with errno %d - %s \n",
5404					       __FUNCTION__, errno, strerror( errno ) );
5405					return( -1 );
5406				}
5407			}
5408			/* name already exists, try another */
5409			i--;
5410			continue;
5411		}
5412	}
5413
5414	if ( my_fd != -1 )
5415		close( my_fd );
5416
5417	return( 0 );
5418
5419} /* create_random_name_at */
5420
5421/*  **************************************************************************************************************
5422 *	Test close, fpathconf, fstat, open, pathconf system calls.
5423 *  **************************************************************************************************************
5424 */
5425int openat_close_test( void * the_argp )
5426{
5427	int		my_err;
5428	int		my_dirfd = -1;
5429	int		my_fd = -1;
5430	int             error_fd = -1;
5431	char *		my_dirpathp = NULL;
5432	char *		my_namep = NULL;
5433	char *		my_pathp = NULL;
5434	ssize_t		my_result;
5435	long		my_pconf_result;
5436	struct stat	my_sb;
5437	char		my_buffer[32];
5438	kern_return_t           my_kr;
5439
5440
5441	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_dirpathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5442        if(my_kr != KERN_SUCCESS){
5443                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5444                goto test_failed_exit;
5445        }
5446
5447	*my_dirpathp = 0x00;
5448	strlcat( my_dirpathp, &g_target_path[0], PATH_MAX );
5449
5450	my_dirfd = openat(AT_FDCWD, my_dirpathp, O_RDONLY, 0 );
5451	if ( my_dirfd == -1 ) {
5452		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5453		printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
5454		goto test_failed_exit;
5455	}
5456
5457	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
5458        if(my_kr != KERN_SUCCESS){
5459                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5460                goto test_failed_exit;
5461        }
5462
5463	*my_namep = 0x00;
5464	if (my_pathp) {
5465		*my_pathp = 0x00;
5466	}
5467
5468	/* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
5469	if (*my_dirpathp == '/') {
5470		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5471		if(my_kr != KERN_SUCCESS){
5472			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5473			goto test_failed_exit;
5474		}
5475	}
5476
5477	/*
5478	 * Some basic openat validation. If pathname is absolute, invalid fd should
5479	 * not matter.
5480	 */
5481
5482	if (*my_dirpathp == '/') {
5483		my_dirfd = openat( INVALID_FD, my_dirpathp, O_RDONLY, 0 );
5484		if ( my_dirfd == -1 ) {
5485			printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5486			printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
5487			printf( "\t Was Absolute pathname, invalid fd, %d, provided as input \n", INVALID_FD);
5488			goto test_failed_exit;
5489		}
5490		close(my_dirfd);
5491
5492	}
5493
5494	my_dirfd = openat( AT_FDCWD, my_dirpathp, O_RDONLY, 0 );
5495	if ( my_dirfd == -1 ) {
5496		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5497		printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
5498		goto test_failed_exit;
5499	}
5500
5501	/* create a test file */
5502	my_err = create_random_name_at( my_dirfd, my_dirpathp, my_namep, NAME_MAX, my_pathp, PATH_MAX, 1 );
5503	if ( my_err != 0 ) {
5504		goto test_failed_exit;
5505	}
5506
5507	/*
5508	 * If pathname is not absolute, an openat relative to a invalid directory fd
5509	 * should not work.
5510	 */
5511	if (my_pathp) {
5512		/*  test O_WRONLY case */
5513		my_fd = openat( INVALID_FD, my_namep, O_WRONLY, 0 );
5514		if ( my_fd != -1 ) {
5515			printf( "openat call relative to invalid dir fd worked\n");
5516			printf( "\t file we attempted to open -> \"%s\" relative to fd -173\n", my_pathp );
5517			goto test_failed_exit;
5518		}
5519	}
5520
5521	/*  test O_WRONLY case */
5522	my_fd = openat( my_dirfd, my_namep, O_WRONLY, 0 );
5523	if ( my_fd == -1 ) {
5524		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5525		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
5526		goto test_failed_exit;
5527	}
5528
5529        /*
5530	 * try to open relative to non-directory fd.
5531	 * It should fail with ENOTDIR.
5532	 */
5533	if ((error_fd = openat(my_fd, my_namep, O_WRONLY, 0)) != -1) {
5534		printf( "openat call succeded with fd being a non-directory fd\n");
5535		printf( "\t file we attempted to open (reltive to itself)-> \"%s\" \n", my_pathp );
5536		close(error_fd);
5537		goto test_failed_exit;
5538	} else if (errno != ENOTDIR) {
5539		printf( "openat call should have failed with errno 20 (ENOTDIR).  actually failed with %d - \"%s\" \n", my_err, strerror( my_err) );
5540	}
5541
5542	my_pconf_result = fpathconf( my_fd, _PC_NAME_MAX );
5543	if ( my_pconf_result == -1 ) {
5544		printf( "fpathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
5545		goto test_failed_exit;
5546	}
5547	//	printf( "_PC_NAME_MAX %ld \n", my_pconf_result );
5548	/* results look OK? */
5549	if ( my_pconf_result < 6 ) {
5550		printf( "fpathconf - _PC_NAME_MAX - looks like wrong results \n" );
5551		goto test_failed_exit;
5552	}
5553
5554	/* write some data then try to read it */
5555	my_result = write( my_fd, "kat", 3 );
5556	my_err = errno;
5557	if ( my_result != 3 ) {
5558		if ( sizeof( ssize_t ) > sizeof( int ) ) {
5559			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
5560		}
5561		else {
5562			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
5563		}
5564		goto test_failed_exit;
5565	}
5566
5567	/* Try to read - this should fail since we opened file with O_WRONLY */
5568	my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
5569	my_err = errno;
5570	if ( my_result != -1 ) {
5571		printf( "read call should have failed with errno 9 (EBADF) \n" );
5572		goto test_failed_exit;
5573	}
5574	else if ( my_err != EBADF ) {
5575		printf( "read call should have failed with errno 9 (EBADF).  actually failed with %d - \"%s\" \n", my_err, strerror( my_err) );
5576		goto test_failed_exit;
5577	}
5578
5579	close( my_fd );
5580
5581	/*  test O_TRUNC and O_APPEND case */
5582	my_fd = openat( my_dirfd, my_namep, (O_RDWR | O_TRUNC | O_APPEND), 0 );
5583	if ( my_fd == -1 ) {
5584		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5585		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
5586		goto test_failed_exit;
5587	}
5588
5589	my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
5590	if ( my_result == -1 ) {
5591		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5592		goto test_failed_exit;
5593	}
5594	if ( my_result != 0 ) {
5595		printf( "read failed - should have read 0 bytes. \n" );
5596		goto test_failed_exit;
5597	}
5598
5599	my_result = write( my_fd, "kat", 3 );
5600	my_err = errno;
5601	if ( my_result != 3 ) {
5602		if ( sizeof( ssize_t ) > sizeof( int ) ) {
5603			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
5604		}
5605		else {
5606			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
5607		}
5608		goto test_failed_exit;
5609	}
5610
5611	/* add some more data to the test file - this should be appended */
5612	lseek( my_fd, 0, SEEK_SET );
5613	my_result = write( my_fd, "zzz", 3 );
5614	my_err = errno;
5615	if ( my_result != 3 ) {
5616		if ( sizeof( ssize_t ) > sizeof( int ) ) {
5617			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
5618		}
5619		else {
5620			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
5621		}
5622		goto test_failed_exit;
5623	}
5624
5625	/* now verify the writes */
5626	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
5627	lseek( my_fd, 0, SEEK_SET );
5628	my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
5629	if ( my_result == -1 ) {
5630		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5631		goto test_failed_exit;
5632	}
5633	if ( my_buffer[0] != 'k' || my_buffer[5] != 'z' ) {
5634		printf( "read failed to get correct data \n" );
5635		goto test_failed_exit;
5636	}
5637
5638	/*
5639	 * try to stat relative to non-directory fd.
5640	 * It should fail with ENOTDIR.
5641	 */
5642	if ((fstatat( my_fd, my_namep, &my_sb, 0 )) != -1) {
5643		printf( "fstatat call succeded with fd being a non-directory fd\n");
5644		printf( "\t file we attempted to stat (relative to itself)-> \"%s\" \n", my_pathp );
5645		goto test_failed_exit;
5646	} else if (errno != ENOTDIR) {
5647		printf( "fstatat call should have failed with errno 20 (ENOTDIR).  actually failed with %d - \"%s\" \n", my_err, strerror( my_err) );
5648	}
5649
5650	/* test fstatat */
5651	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
5652	if ( my_err == -1 ) {
5653		printf( "fstatat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5654		goto test_failed_exit;
5655	}
5656	if ( my_sb.st_size != 6 ) {
5657		printf( "fstatat call failed - st_size is wrong \n" );
5658		goto test_failed_exit;
5659	}
5660	if ( !S_ISREG( my_sb.st_mode ) ) {
5661		printf( "fstatat call failed - st_mode does not indicate regular file \n" );
5662		goto test_failed_exit;
5663	}
5664
5665	my_err = 0;
5666	goto test_passed_exit;
5667
5668test_failed_exit:
5669	my_err = -1;
5670
5671test_passed_exit:
5672	if ( my_fd != -1 )
5673		close( my_fd );
5674
5675	if ( my_pathp != NULL ) {
5676		remove(my_pathp);
5677		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
5678	}
5679
5680	if ( my_namep ) {
5681		unlinkat( my_dirfd, my_pathp, 0 );
5682		vm_deallocate(mach_task_self(), (vm_address_t)my_namep, NAME_MAX);
5683	}
5684
5685	if ( my_dirfd != -1)
5686		close(my_dirfd);
5687
5688	if ( my_dirpathp != NULL ) {
5689		vm_deallocate(mach_task_self(), (vm_address_t)my_dirpathp, PATH_MAX);
5690	}
5691
5692	return( my_err );
5693}
5694
5695/*  **************************************************************************************************************
5696 *	Test linkat, fstatat and unlinkat system calls.
5697 *  **************************************************************************************************************
5698 */
5699int linkat_fstatat_unlinkat_test( void * the_argp )
5700{
5701	int			my_err;
5702	int			my_dirfd = -1;
5703	int			my_fd = -1;
5704	char *			my_dirpathp = NULL;
5705	char *			my_namep = NULL;
5706	char *			my_pathp = NULL;
5707	char *			my_name2p = NULL;
5708	nlink_t			my_link_count;
5709	ssize_t			my_result;
5710	struct stat		my_sb;
5711	kern_return_t           my_kr;
5712
5713
5714	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_dirpathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5715        if(my_kr != KERN_SUCCESS){
5716                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5717                goto test_failed_exit;
5718        }
5719
5720	*my_dirpathp = 0x00;
5721	strlcat( my_dirpathp, &g_target_path[0], PATH_MAX );
5722
5723	my_dirfd = openat(AT_FDCWD, my_dirpathp, O_RDONLY, 0 );
5724	if ( my_dirfd == -1 ) {
5725		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5726		printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
5727		goto test_failed_exit;
5728	}
5729
5730	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
5731        if(my_kr != KERN_SUCCESS){
5732                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5733                goto test_failed_exit;
5734        }
5735
5736	*my_namep = 0x00;
5737	if (my_pathp) {
5738		*my_pathp = 0x00;
5739	}
5740
5741	/* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
5742	if (*my_dirpathp == '/') {
5743		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5744		if(my_kr != KERN_SUCCESS){
5745			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5746			goto test_failed_exit;
5747		}
5748	}
5749
5750	/* create a test file */
5751	my_err = create_random_name_at( my_dirfd, my_dirpathp, my_namep, NAME_MAX, my_pathp, PATH_MAX, 1 );
5752	if ( my_err != 0 ) {
5753		goto test_failed_exit;
5754	}
5755
5756	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_name2p, NAME_MAX, VM_FLAGS_ANYWHERE);
5757        if(my_kr != KERN_SUCCESS){
5758                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5759                goto test_failed_exit;
5760        }
5761
5762	*my_name2p = 0x00;
5763
5764	/* now create a name for the link file */
5765	strlcat( my_name2p, my_namep, NAME_MAX );
5766	strlcat( my_name2p, "link", NAME_MAX );
5767
5768	/* get the current link count */
5769	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
5770	if ( my_err != 0 ) {
5771		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5772		goto test_failed_exit;
5773	}
5774	my_link_count = my_sb.st_nlink;
5775
5776	/* Double check with absolute path name */
5777	if (my_pathp) {
5778		my_err = fstatat(INVALID_FD, my_pathp, &my_sb, 0 );
5779		if ( my_err != 0 ) {
5780			printf( "fstatat with INVALID_FD and absolute pathname failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5781			goto test_failed_exit;
5782		}
5783		if (my_link_count != my_sb.st_nlink) {
5784			printf( "fstatat call did not return correct number of links" );
5785			goto test_failed_exit;
5786		}
5787	}
5788
5789	/* check file size (should be 0) */
5790	if ( my_sb.st_size != 0 ) {
5791		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
5792		printf( "st_size is not 0 \n" );
5793		goto test_failed_exit;
5794	}
5795
5796	/* change file size */
5797	my_fd = openat(my_dirfd, my_namep, O_RDWR, 0 );
5798	if ( my_fd == -1 ) {
5799		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5800		printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
5801		goto test_failed_exit;
5802	}
5803
5804	my_result = write( my_fd, "kat", 3 );
5805	my_err = errno;
5806	if ( my_result != 3 ) {
5807		if ( sizeof( ssize_t ) > sizeof( int ) ) {
5808			printf( "write failed.  should have written 3 bytes actually wrote -  %ld \n", (long int) my_result );
5809		}
5810		else {
5811			printf( "write failed.  should have written 3 bytes actually wrote -  %d \n", (int) my_result );
5812		}
5813		goto test_failed_exit;
5814	}
5815	close( my_fd );
5816	my_fd = -1;
5817
5818	/* now link another file to our test file and recheck link count */
5819	/* N.B. - HFS only supports AT_SYMLINK_FOLLOW */
5820	my_err = linkat( my_dirfd, my_namep, my_dirfd, my_name2p, AT_SYMLINK_FOLLOW );
5821	if ( my_err != 0 ) {
5822		printf( "linkat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5823		goto test_failed_exit;
5824	}
5825	my_err = fstatat( my_dirfd, my_pathp, &my_sb, 0 );
5826	if ( my_err != 0 ) {
5827		printf( "fstatat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5828		goto test_failed_exit;
5829	}
5830	if ( (my_link_count + 1) != my_sb.st_nlink ) {
5831		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
5832		printf( "incorrect st_nlink \n" );
5833		goto test_failed_exit;
5834	}
5835
5836	/* check file size (should be 3) */
5837	if ( my_sb.st_size != 3 ) {
5838		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
5839		printf( "st_size is not 3 \n" );
5840		goto test_failed_exit;
5841	}
5842
5843	/* now make sure unlink works OK */
5844	my_err = unlinkat( my_dirfd, my_name2p, 0 );
5845	if ( my_err != 0 ) {
5846		printf( "unlinkat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5847		goto test_failed_exit;
5848	}
5849	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
5850	if ( my_err != 0 ) {
5851		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5852		goto test_failed_exit;
5853	}
5854	if ( my_link_count != my_sb.st_nlink ) {
5855		printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
5856		printf( "incorrect st_nlink \n" );
5857		goto test_failed_exit;
5858	}
5859
5860	my_err = 0;
5861	goto test_passed_exit;
5862
5863test_failed_exit:
5864	my_err = -1;
5865
5866test_passed_exit:
5867	if ( my_fd != -1 )
5868		close( my_fd );
5869
5870	if ( my_name2p != NULL ) {
5871		(void)unlinkat( my_dirfd, my_name2p, 0 );
5872		vm_deallocate(mach_task_self(), (vm_address_t)my_name2p, NAME_MAX);
5873	}
5874
5875	if ( my_namep != NULL ) {
5876		(void)unlinkat( my_dirfd, my_name2p, 0 );
5877		vm_deallocate(mach_task_self(), (vm_address_t)my_name2p, NAME_MAX);
5878	}
5879
5880	if ( my_pathp != NULL ) {
5881		remove( my_pathp );
5882		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
5883	}
5884
5885	if ( my_dirpathp != NULL ) {
5886		vm_deallocate(mach_task_self(), (vm_address_t)my_dirpathp, PATH_MAX);
5887	}
5888
5889	if ( my_dirfd != -1 )
5890		close( my_dirfd );
5891
5892	return( my_err );
5893}
5894
5895/*  **************************************************************************************************************
5896 *	Test faccessat, fchmodat and fchmod system calls.
5897 *  **************************************************************************************************************
5898 */
5899int faccessat_fchmodat_fchmod_test( void * the_argp )
5900{
5901	int		error_occurred;
5902	int             is_absolute_path = 0;
5903	int		my_err;
5904	int		my_dirfd = -1;
5905	int		my_fd = -1;
5906
5907	char *		my_dirpathp = NULL;
5908	char *		my_namep = NULL;
5909	char *		my_pathp = NULL;
5910
5911	uid_t		euid,ruid;
5912	struct stat	my_sb;
5913
5914	FILE *		file_handle;
5915
5916	kern_return_t	my_kr;
5917
5918
5919        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_dirpathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5920        if(my_kr != KERN_SUCCESS){
5921                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5922                goto test_failed_exit;
5923        }
5924
5925	*my_dirpathp = 0x00;
5926	strlcat( my_dirpathp, &g_target_path[0], PATH_MAX );
5927
5928	/*
5929	 * Some basic openat validation. If pathname is absolute, an invalid fd should
5930	 * not matter.
5931	 */
5932
5933	if (*my_dirpathp == '/') {
5934		is_absolute_path = 1;
5935		my_dirfd = openat(INVALID_FD, my_dirpathp, O_RDONLY, 0 );
5936		if ( my_dirfd == -1 ) {
5937			printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5938			printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
5939			printf( "\t Was Absolute pathname, invalid fd, %d, provided as input \n", INVALID_FD);
5940			goto test_failed_exit;
5941		}
5942		close( my_dirfd );
5943	}
5944
5945	my_dirfd = openat(AT_FDCWD, my_dirpathp, O_RDONLY, 0 );
5946	if ( my_dirfd == -1 ) {
5947		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
5948		printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
5949		goto test_failed_exit;
5950	}
5951
5952	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
5953        if(my_kr != KERN_SUCCESS){
5954                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5955                goto test_failed_exit;
5956        }
5957
5958	*my_namep = 0x00;
5959
5960	if (is_absolute_path) {
5961		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5962		if(my_kr != KERN_SUCCESS){
5963			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5964			goto test_failed_exit;
5965		}
5966
5967		*my_pathp = 0x00;
5968	}
5969
5970	/* create a test file */
5971	my_err = create_random_name_at(my_dirfd, my_dirpathp, my_namep, NAME_MAX, my_pathp, PATH_MAX, 1);
5972	if ( my_err != 0 ) {
5973		goto test_failed_exit;
5974	}
5975
5976	/* test chmod */
5977	my_err = fchmodat(my_dirfd, my_namep, S_IRWXU, 0);
5978	if ( my_err == -1 ) {
5979		printf( "chmod call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5980		goto test_failed_exit;
5981	}
5982
5983	my_err = fchmodat( my_dirfd, my_namep, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), 0 );
5984	if ( my_err == -1 ) {
5985		printf( "chmod call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
5986		goto test_failed_exit;
5987	}
5988
5989	/* test access - this should fail */
5990	my_err = faccessat( my_dirfd, my_namep, (X_OK), 0 );
5991	if ( my_err == 0 ) {
5992		printf( "access call should have failed, but did not. \n" );
5993		goto test_failed_exit;
5994	}
5995	else if ( my_err == -1  ) {
5996		int tmp = 0;
5997		tmp = getuid( );
5998
5999		/* special case when running as root - we get back EPERM when running as root */
6000		my_err = errno;
6001		if ( ( tmp == 0 && my_err != EPERM) || (tmp != 0 && my_err != EACCES) ) {
6002			printf( "access failed with errno %d - %s. \n", my_err, strerror( my_err ) );
6003			goto test_failed_exit;
6004		}
6005	}
6006
6007	/* verify correct modes are set */
6008	/* First check that Absolute path works even with an invalid FD */
6009	if (is_absolute_path) {
6010		my_err = fstatat( INVALID_FD, my_pathp, &my_sb, 0 );
6011		if ( my_err != 0 ) {
6012			printf( "fstatat call failed with an absolute pathname.  got errno %d - %s. \n", errno, strerror( errno ) );
6013			goto test_failed_exit;
6014		}
6015	}
6016
6017	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
6018	if ( my_err != 0 ) {
6019		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6020		goto test_failed_exit;
6021	}
6022
6023	if ( (my_sb.st_mode & (S_IRWXO | S_IXGRP)) != 0 ||
6024	    (my_sb.st_mode & (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == 0 ) {
6025		printf( "chmod call appears to have failed.  stat shows incorrect values in st_mode! \n" );
6026		goto test_failed_exit;
6027	}
6028
6029
6030	/*  another test for the access system call  -- refer ro radar# 6725311 */
6031
6032
6033	/*
6034	 * This test makes sure that the access system call does not give the current user extra
6035	 * permissions on files the current user does not own. From radar #6725311, this could
6036	 * happen when the current user calls access() on a file owned by the current user in
6037	 * the same directory as the other files not owned by the current user.
6038	 *
6039	 * Note: This test expects that the effective uid (euid) is set to root.
6040	 *
6041	 */
6042
6043	/* Create a file that root owns  */
6044	file_handle = fopen(FILE_NOTME, "w");
6045	fclose(file_handle);
6046
6047	/* Currently running as root (through setreuid manipulation), switch to running as the current user. */
6048	euid = geteuid();
6049	ruid = getuid();
6050	setreuid(ruid, ruid);
6051
6052	/* Create a file that the current user owns  */
6053	file_handle = fopen(FILE_ME, "w");
6054	fclose(file_handle);
6055
6056	error_occurred = 0;
6057
6058	/* Try to remove the file owned by root (this should fail). */
6059	my_err = unlinkat( AT_FDCWD, FILE_NOTME, 0 );
6060
6061	if (my_err < 0) {
6062		my_err = errno;
6063	}
6064
6065	if (my_err == 0) {
6066		printf("Unresolved: First attempt deleted '" FILE_NOTME "'! \n");
6067		error_occurred = 1;
6068	} else {
6069		printf("Passed: First attempt to delete '" FILE_NOTME "'  failed with error %d - %s.\n", my_err, strerror( my_err ));
6070
6071		/* Set _DELETE_OK on a file that the current user owns */
6072		faccessat(AT_FDCWD, FILE_ME, _DELETE_OK, 0 );
6073
6074		/* Try to remove the file owned by root again (should give us: EPERM [13]) */
6075		my_err = unlinkat(AT_FDCWD, FILE_NOTME, 0);
6076
6077		if (my_err < 0) {
6078			my_err = errno;
6079		}
6080
6081		if (my_err == 0) {
6082			printf("Failed: Second attempt deleted '" FILE_NOTME "'!\n");
6083			error_occurred = 1;
6084		} else if (my_err == 13) {
6085			printf("Passed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
6086		} else {
6087			printf("Failed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
6088			error_occurred = 1;
6089		}
6090	}
6091
6092	/* Reset to running as root */
6093	setreuid(ruid, euid);
6094
6095	if(error_occurred == 1) {
6096		goto test_failed_exit;
6097	}
6098
6099
6100	/* end of test*/
6101
6102
6103	/* test fchmod */
6104	my_fd = openat( my_dirfd, my_namep, O_RDONLY, 0);
6105	if ( my_fd == -1 ) {
6106		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
6107		printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
6108		goto test_failed_exit;
6109	}
6110
6111	my_err = fchmod( my_fd, S_IRWXU );
6112	if ( my_err == -1 ) {
6113		printf( "fchmod call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6114		goto test_failed_exit;
6115	}
6116
6117	my_err = fstatat( INVALID_FD, my_pathp, &my_sb, 0 );
6118	if ( my_err != 0 ) {
6119		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6120		goto test_failed_exit;
6121	}
6122
6123	/* verify correct modes are set */
6124	if ( (my_sb.st_mode & (S_IRWXG | S_IRWXO)) != 0 ||
6125	    (my_sb.st_mode & (S_IRWXU)) == 0 ) {
6126		printf( "fchmod call appears to have failed.  stat shows incorrect values in st_mode! \n" );
6127		goto test_failed_exit;
6128	}
6129
6130	my_err = 0;
6131	goto test_passed_exit;
6132
6133test_failed_exit:
6134	my_err = -1;
6135
6136test_passed_exit:
6137	if ( my_fd != -1 )
6138		close( my_fd );
6139	if ( my_pathp != NULL ) {
6140		remove( my_pathp );
6141		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
6142	}
6143	if ( my_namep != NULL ) {
6144		unlinkat(my_dirfd, my_namep, 0);
6145		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, NAME_MAX);
6146
6147	}
6148
6149	if ( my_dirfd != -1)
6150		close( my_dirfd);
6151
6152	if ( my_dirpathp != NULL ) {
6153		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
6154	}
6155
6156	return( my_err );
6157}
6158
6159/*  **************************************************************************************************************
6160 *	Test fchownat, fchown, readlinkat, symlinkat system calls.
6161 *  **************************************************************************************************************
6162 */
6163int fchownat_fchown_symlinkat_test( void * the_argp )
6164{
6165	int			my_err, my_group_count, i;
6166	int			my_fd = -1;
6167	int			my_dirfd = -1;
6168	char *			my_dirpathp = NULL;
6169	char *			my_namep = NULL;
6170	char *			my_link_namep = NULL;
6171	char *			my_pathp = NULL;
6172	char *			my_link_pathp = NULL;
6173	int			is_absolute_path = 0;
6174	uid_t			my_orig_uid;
6175	gid_t			my_orig_gid, my_new_gid1 = 0, my_new_gid2 = 0;
6176	ssize_t			my_result;
6177	struct stat		my_sb;
6178	gid_t			my_groups[ NGROUPS_MAX ];
6179	char			my_buffer[ 64 ];
6180	kern_return_t           my_kr;
6181
6182
6183	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_dirpathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6184        if(my_kr != KERN_SUCCESS){
6185                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6186                goto test_failed_exit;
6187        }
6188
6189	*my_dirpathp = 0x00;
6190	strlcat( my_dirpathp, &g_target_path[0], PATH_MAX );
6191
6192	/*
6193	 * Some basic openat validation. If pathname is absolute, an invalid fd should
6194	 * not matter.
6195	 */
6196	if (*my_dirpathp == '/') {
6197		is_absolute_path = 1;
6198		my_dirfd = openat(INVALID_FD, my_dirpathp, O_RDONLY, 0 );
6199		if ( my_dirfd == -1 ) {
6200			printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
6201			printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
6202			printf( "\t Was Absolute pathname, invalid fd, %d, provided as input \n", INVALID_FD);
6203			goto test_failed_exit;
6204		}
6205		close( my_dirfd );
6206	}
6207
6208	my_dirfd = openat(AT_FDCWD, my_dirpathp, O_RDONLY, 0 );
6209	if ( my_dirfd == -1 ) {
6210		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
6211		printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
6212		goto test_failed_exit;
6213	}
6214
6215	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
6216        if(my_kr != KERN_SUCCESS){
6217                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6218                goto test_failed_exit;
6219        }
6220
6221	*my_namep = 0x00;
6222
6223	if (is_absolute_path) {
6224		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6225		if(my_kr != KERN_SUCCESS){
6226			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6227			goto test_failed_exit;
6228		}
6229
6230		*my_pathp = 0x00;
6231	}
6232
6233	/* create a test file */
6234	my_err = create_random_name_at(my_dirfd, my_dirpathp, my_namep, NAME_MAX, my_pathp, PATH_MAX, 1);
6235	if ( my_err != 0 ) {
6236		goto test_failed_exit;
6237	}
6238
6239	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_link_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
6240        if(my_kr != KERN_SUCCESS){
6241                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6242                goto test_failed_exit;
6243        }
6244
6245	*my_link_namep = 0x00;
6246
6247	if (is_absolute_path) {
6248		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_link_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6249		if(my_kr != KERN_SUCCESS){
6250			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6251			goto test_failed_exit;
6252		}
6253
6254		*my_link_pathp = 0x00;
6255	}
6256
6257	/* get a name for the link (to create the symlink later) */
6258	my_err = create_random_name_at(my_dirfd, my_dirpathp, my_link_namep, NAME_MAX, my_link_pathp, PATH_MAX, 0 );
6259	if ( my_err != 0 ) {
6260		goto test_failed_exit;
6261	}
6262
6263	if ( !_prime_groups() ) {
6264		goto test_failed_exit;
6265	}
6266
6267	/* set up by getting a list of groups */
6268	my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
6269
6270	if ( my_group_count == -1 || my_group_count < 1 ) {
6271		printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6272		goto test_failed_exit;
6273	}
6274
6275	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
6276	if ( my_err != 0 ) {
6277		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6278		goto test_failed_exit;
6279	}
6280
6281	/* now change group owner to something other than current value */
6282	my_orig_gid = my_sb.st_gid;
6283	my_orig_uid = my_sb.st_uid;
6284
6285	for ( i = 0; i < my_group_count; i++ ) {
6286		if ( my_orig_gid != my_groups[ i ] ) {
6287			if ( my_new_gid1 == 0 ) {
6288				my_new_gid1 = my_groups[ i ];
6289			}
6290			else if( my_new_gid1 != my_groups[ i ] ) {
6291				my_new_gid2 = my_groups[ i ];
6292				break;
6293			}
6294		}
6295	}
6296	if ( i >= my_group_count ) {
6297		printf( "not enough groups to choose from.  st_gid is the same as current groups! \n" );
6298		goto test_failed_exit;
6299	}
6300
6301	my_err = fchownat( my_dirfd, my_namep, my_orig_uid, my_new_gid1, 0 );
6302	if ( my_err != 0 ) {
6303		printf( "chown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6304		goto test_failed_exit;
6305	}
6306
6307	/* make sure the group owner was changed */
6308	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
6309	if ( my_err != 0 ) {
6310		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6311		goto test_failed_exit;
6312	}
6313	if ( my_sb.st_gid == my_orig_gid ) {
6314		printf( "chown call failed.  st_gid is not correct! \n" );
6315		goto test_failed_exit;
6316	}
6317
6318	/* change group owner back using fchown */
6319	if (is_absolute_path) {
6320		my_fd = openat( INVALID_FD, my_pathp, O_RDWR, 0 );
6321	} else {
6322		my_fd = openat( my_dirfd, my_namep, O_RDWR, 0 );
6323	}
6324
6325	if ( my_fd == -1 ) {
6326		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
6327		printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
6328		goto test_failed_exit;
6329	}
6330
6331	my_err = fchown( my_fd, my_orig_uid, my_new_gid2 );
6332	if ( my_err != 0 ) {
6333		printf( "fchown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6334		goto test_failed_exit;
6335	}
6336
6337	/* make sure the group owner was changed back to the original value */
6338	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
6339	if ( my_err != 0 ) {
6340		printf( "fstatat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6341		goto test_failed_exit;
6342	}
6343	if ( my_sb.st_gid == my_new_gid1 ) {
6344		printf( "fchown call failed.  st_gid is not correct! \n" );
6345		goto test_failed_exit;
6346	}
6347
6348	/* create a link file and test fstatat(..., AT_SYMLINK_NOFOLLOW) */
6349	my_err = symlinkat( my_namep, my_dirfd, my_link_namep );
6350	if ( my_err != 0 ) {
6351		printf( "symlinkat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6352		goto test_failed_exit;
6353	}
6354
6355	my_err = fstatat( my_dirfd, my_link_namep, &my_sb, AT_SYMLINK_NOFOLLOW );
6356	if ( my_err != 0 ) {
6357		printf( "fstatat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6358		goto test_failed_exit;
6359	}
6360
6361	/* now change group owner to something other than current value */
6362	my_orig_gid = my_sb.st_gid;
6363	my_orig_uid = my_sb.st_uid;
6364	my_err = fchownat( my_dirfd, my_link_namep, my_orig_uid, my_new_gid1, AT_SYMLINK_NOFOLLOW );
6365	if ( my_err != 0 ) {
6366		printf( "fchownat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6367		goto test_failed_exit;
6368	}
6369
6370	/* make sure the group owner was changed to new value */
6371	my_err = fstatat( my_dirfd, my_link_namep, &my_sb, AT_SYMLINK_NOFOLLOW );
6372	if ( my_err != 0 ) {
6373		printf( "fstatat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6374		goto test_failed_exit;
6375	}
6376	if ( my_sb.st_gid == my_new_gid2 ) {
6377		printf( "fchownat call failed.  st_gid is not correct! \n" );
6378		goto test_failed_exit;
6379	}
6380
6381	/* make sure we can read the symlink file */
6382	my_result = readlinkat( my_dirfd, my_link_namep, &my_buffer[0], sizeof(my_buffer) );
6383	if ( my_result == -1 ) {
6384		printf( "readlinkat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
6385		goto test_failed_exit;
6386	}
6387	/* make sure we read some data */
6388	if ( my_result < 1 ) {
6389		printf( "readlinkat failed to read any data. \n" );
6390		goto test_failed_exit;
6391	}
6392
6393	my_err = 0;
6394	goto test_passed_exit;
6395
6396test_failed_exit:
6397	my_err = -1;
6398
6399test_passed_exit:
6400	if ( my_fd != -1 )
6401		close( my_fd );
6402	if  ( my_namep ) {
6403		unlinkat( my_dirfd, my_namep, 0);
6404		vm_deallocate(mach_task_self(), (vm_address_t)my_namep, NAME_MAX);
6405	}
6406	if ( my_pathp != NULL ) {
6407		remove( my_pathp );
6408		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
6409	}
6410	if  ( my_link_namep ) {
6411		unlinkat( my_dirfd, my_link_namep, 0);
6412		vm_deallocate(mach_task_self(), (vm_address_t)my_link_namep, NAME_MAX);
6413	}
6414	if ( my_link_pathp != NULL ) {
6415		unlink( my_link_pathp );
6416		vm_deallocate(mach_task_self(), (vm_address_t)my_link_pathp, PATH_MAX);
6417	}
6418	if ( my_dirfd != -1 )
6419		close(my_dirfd);
6420
6421	if ( my_dirpathp != NULL ) {
6422		vm_deallocate(mach_task_self(), (vm_address_t)my_dirpathp, PATH_MAX);
6423	}
6424
6425
6426	return( my_err );
6427}
6428
6429/*  **************************************************************************************************************
6430 *	Test mkdirat, unlinkat, umask system calls.
6431 *  **************************************************************************************************************
6432 */
6433int mkdirat_unlinkat_umask_test( void * the_argp )
6434{
6435	int				my_err;
6436	int				my_dirfd = -1;
6437	int				my_fd = -1;
6438	int				did_umask = 0;
6439	char *				my_dirpathp = NULL;
6440	char *				my_namep = NULL;
6441	char *				my_pathp = NULL;
6442	mode_t				my_orig_mask;
6443	struct stat			my_sb;
6444	kern_return_t			my_kr;
6445
6446	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_dirpathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6447        if(my_kr != KERN_SUCCESS){
6448                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6449                goto test_failed_exit;
6450        }
6451
6452	*my_dirpathp = 0x00;
6453	strlcat( my_dirpathp, &g_target_path[0], PATH_MAX );
6454
6455	my_dirfd = openat(AT_FDCWD, my_dirpathp, O_RDONLY, 0 );
6456	if ( my_dirfd == -1 ) {
6457		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
6458		printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
6459		goto test_failed_exit;
6460	}
6461
6462	/* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
6463	if (*my_dirpathp == '/') {
6464		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6465		if(my_kr != KERN_SUCCESS){
6466			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6467			goto test_failed_exit;
6468		}
6469	}
6470
6471	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
6472        if(my_kr != KERN_SUCCESS){
6473                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6474                goto test_failed_exit;
6475        }
6476
6477	*my_namep = 0x00;
6478	if (my_pathp) {
6479		*my_pathp = 0x00;
6480	}
6481
6482	/* get a random name to use with mkdirat (don't create) */
6483	my_err = create_random_name_at( my_dirfd, my_dirpathp, my_namep, NAME_MAX, my_pathp, PATH_MAX, 0 );
6484	if ( my_err != 0 ) {
6485		goto test_failed_exit;
6486	}
6487
6488	/* set umask to clear WX for other and group and clear X for user */
6489	my_orig_mask = umask( (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) );
6490	did_umask = 1;
6491
6492	/* create a directory with RWX for user, group, other (which should be limited by umask) */
6493	my_err = mkdirat( my_dirfd, my_namep, (S_IRWXU | S_IRWXG | S_IRWXO) );
6494	if ( my_err == -1 ) {
6495		printf( "mkdirat failed with error %d - \"%s\" \n", errno, strerror( errno) );
6496		goto test_failed_exit;
6497	}
6498
6499	/* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/
6500	my_err = fstatat( my_dirfd, my_pathp, &my_sb, 0 );
6501	if ( my_err != 0 ) {
6502		printf( "fstat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
6503		goto test_failed_exit;
6504	}
6505	if ( (my_sb.st_mode & (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH)) != 0 ) {
6506		printf( "umask did not limit modes as it should have \n" );
6507		goto test_failed_exit;
6508	}
6509
6510	/* get rid of our test directory */
6511	my_err = unlinkat( my_dirfd, my_namep, AT_REMOVEDIR );
6512	if ( my_err == -1 ) {
6513		printf( "unlinkat(..., AT_REMOVEDIR)  failed with error %d - \"%s\" \n", errno, strerror( errno) );
6514		goto test_failed_exit;
6515	}
6516	my_err = 0;
6517	goto test_passed_exit;
6518
6519test_failed_exit:
6520	my_err = -1;
6521
6522test_passed_exit:
6523	if ( my_fd != -1 )
6524		close( my_fd );
6525
6526	if  ( my_namep ) {
6527		unlinkat( my_dirfd, my_namep, AT_REMOVEDIR );
6528		vm_deallocate(mach_task_self(), (vm_address_t)my_namep, NAME_MAX);
6529	}
6530
6531	if ( my_pathp != NULL ) {
6532		rmdir( my_pathp );
6533		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
6534	}
6535
6536	if ( my_dirfd != -1 )
6537		close(my_dirfd);
6538
6539	if ( my_dirpathp != NULL ) {
6540		vm_deallocate(mach_task_self(), (vm_address_t)my_dirpathp, PATH_MAX);
6541	}
6542
6543	if ( did_umask != 0 ) {
6544		umask( my_orig_mask );
6545	}
6546
6547	return( my_err );
6548}
6549
6550/*  **************************************************************************************************************
6551 *	Test renameat, fstatat system calls.
6552 *  **************************************************************************************************************
6553 */
6554int renameat_test( void * the_argp )
6555{
6556	int			my_err;
6557	int			my_dirfd = -1;
6558	char *			my_dirpathp = NULL;
6559	char *			my_namep = NULL;
6560	char *			my_pathp = NULL;
6561	char *			my_new_namep = NULL;
6562	char *			my_new_pathp = NULL;
6563	ino_t			my_file_id;
6564	struct stat		my_sb;
6565	kern_return_t           my_kr;
6566
6567	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_dirpathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6568        if(my_kr != KERN_SUCCESS){
6569                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6570                goto test_failed_exit;
6571        }
6572
6573	*my_dirpathp = 0x00;
6574	strlcat( my_dirpathp, &g_target_path[0], PATH_MAX );
6575
6576	my_dirfd = openat(AT_FDCWD, my_dirpathp, O_RDONLY, 0 );
6577	if ( my_dirfd == -1 ) {
6578		printf( "openat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
6579		printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp );
6580		goto test_failed_exit;
6581	}
6582
6583	/* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
6584	if (*my_dirpathp == '/') {
6585		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6586		if(my_kr != KERN_SUCCESS){
6587			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6588			goto test_failed_exit;
6589		}
6590	}
6591
6592	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
6593        if(my_kr != KERN_SUCCESS){
6594                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6595                goto test_failed_exit;
6596        }
6597
6598	*my_namep = 0x00;
6599	if (my_pathp) {
6600		*my_pathp = 0x00;
6601	}
6602
6603	/* create random file */
6604	my_err = create_random_name_at( my_dirfd, my_dirpathp, my_namep, NAME_MAX, my_pathp, PATH_MAX, 1 );
6605	if ( my_err != 0 ) {
6606		goto test_failed_exit;
6607	}
6608
6609
6610	/* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
6611	if (*my_dirpathp == '/') {
6612		my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6613		if(my_kr != KERN_SUCCESS){
6614			printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6615			goto test_failed_exit;
6616		}
6617	}
6618
6619	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_namep, NAME_MAX, VM_FLAGS_ANYWHERE);
6620        if(my_kr != KERN_SUCCESS){
6621                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6622                goto test_failed_exit;
6623        }
6624
6625	*my_new_namep = 0x00;
6626	if (my_new_pathp) {
6627		*my_new_pathp = 0x00;
6628	}
6629
6630	/* create random file */
6631	my_err = create_random_name_at( my_dirfd, my_dirpathp, my_new_namep, NAME_MAX, my_new_pathp, PATH_MAX, 0 );
6632	if ( my_err != 0 ) {
6633		goto test_failed_exit;
6634	}
6635
6636	/* save file ID for later use */
6637	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
6638	if ( my_err != 0 ) {
6639		printf( "fstatat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
6640		goto test_failed_exit;
6641	}
6642	my_file_id = my_sb.st_ino;
6643
6644	/* test rename */
6645	my_err = renameat( my_dirfd, my_namep, my_dirfd, my_new_namep );
6646	if ( my_err == -1 ) {
6647		printf( "rename - failed with error %d - \"%s\" \n", errno, strerror( errno) );
6648		goto test_failed_exit;
6649	}
6650
6651	/* make sure old name is no longer there */
6652	my_err = fstatat( my_dirfd, my_namep, &my_sb, 0 );
6653	if ( my_err == 0 ) {
6654		printf( "renameat call failed - found old name \n" );
6655		goto test_failed_exit;
6656	}
6657
6658	/* make sure new name is there and is correct file id */
6659	my_err = fstatat( my_dirfd, my_new_namep, &my_sb, 0 );
6660	if ( my_err != 0 ) {
6661		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
6662		goto test_failed_exit;
6663	}
6664	if ( my_file_id != my_sb.st_ino ) {
6665		printf( "rename failed - wrong file id \n" );
6666		goto test_failed_exit;
6667	}
6668
6669	/* cross check with absolute path and invalid fd */
6670	if (my_new_pathp) {
6671		my_err = fstatat( INVALID_FD, my_new_pathp, &my_sb, 0 );
6672		if ( my_err != 0 ) {
6673			printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
6674			goto test_failed_exit;
6675		}
6676		if ( my_file_id != my_sb.st_ino ) {
6677			printf( "rename failed - wrong file id \n" );
6678			goto test_failed_exit;
6679		}
6680	}
6681
6682	my_err = 0;
6683	goto test_passed_exit;
6684
6685test_failed_exit:
6686	my_err = -1;
6687
6688test_passed_exit:
6689	if ( my_pathp != NULL ) {
6690		remove( my_pathp );
6691		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
6692	}
6693	if ( my_new_pathp != NULL ) {
6694		remove( my_new_pathp );
6695		vm_deallocate(mach_task_self(), (vm_address_t)my_new_pathp, PATH_MAX);
6696	}
6697	return( my_err );
6698}
6699
6700/*  **************************************************************************************************************
6701 *	Test task_set_exception_ports, host_set_exception_ports
6702 *  **************************************************************************************************************
6703 */
6704static int __get_except_port(int which, mach_port_t *portp,
6705			     exception_behavior_t *behaviorp,
6706			     thread_state_flavor_t *flavorp)
6707{
6708        exception_mask_t masks[EXC_TYPES_COUNT];
6709        mach_msg_type_number_t nmasks = 0;
6710        exception_port_t ports[EXC_TYPES_COUNT];
6711        exception_behavior_t behaviors[EXC_TYPES_COUNT];
6712        thread_state_flavor_t flavors[EXC_TYPES_COUNT];
6713
6714	*portp = MACH_PORT_NULL;
6715	*behaviorp = 0;
6716	*flavorp = 0;
6717
6718        kern_return_t kr = KERN_FAILURE;
6719        if (which == 0) { /* host port */
6720                kr = host_get_exception_ports(mach_host_self(), EXC_MASK_BAD_ACCESS,
6721                                masks, &nmasks, ports, behaviors, flavors);
6722	} else if (which == 1) { /* task port */
6723                kr = task_get_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS,
6724                                masks, &nmasks, ports, behaviors, flavors);
6725        } else if (which == 2) { /* thread_port */
6726                kr = thread_get_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS,
6727                                masks, &nmasks, ports, behaviors, flavors);
6728        } else {
6729		printf("ERROR: invalid 'which' in %s\n", __func__);
6730		return -1;
6731	}
6732        if (kr != KERN_SUCCESS) {
6733		printf("ERROR getting %s exception port!\n", which == 0 ? "task" : "host");
6734		return -1;
6735	}
6736        *portp = ports[0];
6737	*behaviorp = behaviors[0];
6738	*flavorp = flavors[0];
6739
6740	return 0;
6741}
6742
6743int set_exception_ports_test( void * the_argp )
6744{
6745	int           testFlavor = -900000;
6746	kern_return_t ret;
6747	mach_port_t   exception_port;
6748
6749	mach_port_t           old_except_port;
6750	exception_behavior_t  old_behavior;
6751	thread_state_flavor_t old_flavor;
6752
6753
6754	ret = mach_port_allocate( mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &exception_port );
6755	if (ret != KERN_SUCCESS) {
6756		printf("ERROR allocating new exception port?!\n");
6757		return -1;
6758	}
6759	ret = mach_port_insert_right( mach_task_self(), exception_port, exception_port, MACH_MSG_TYPE_MAKE_SEND );
6760	if (ret != KERN_SUCCESS) {
6761		printf("ERROR inserting send right into new exception port?!\n");
6762		goto test_failed_exit;
6763	}
6764
6765	if (__get_except_port(2, &old_except_port, &old_behavior, &old_flavor) < 0)
6766		goto test_failed_exit;
6767
6768	ret = thread_set_exception_ports( mach_thread_self(),
6769					  EXC_MASK_BAD_ACCESS,
6770					  exception_port,
6771					  EXCEPTION_STATE_IDENTITY,
6772					  testFlavor );
6773	/*
6774	 * this test _fails_ if we successfully set the exception port
6775	 * with an invalid thread flavor
6776	 */
6777	if (ret == KERN_SUCCESS) {
6778		thread_set_exception_ports( mach_thread_self(),
6779					    EXC_MASK_BAD_ACCESS,
6780					    old_except_port, old_behavior, old_flavor );
6781		printf("thread_set_exception_ports failed: expected !KERN_SUCCESS for flavor %d\n", testFlavor);
6782		goto test_failed_exit;
6783	}
6784
6785	/*
6786	 * so far, so good: the thread_set_exception_ports call failed,
6787	 * so we don't need to reset anything, but we do need to
6788	 * drop our reference to the old exception port we grabbed.
6789	 */
6790	mach_port_deallocate( mach_task_self(), old_except_port );
6791
6792	if (__get_except_port(1, &old_except_port, &old_behavior, &old_flavor) < 0)
6793		goto test_failed_exit;
6794
6795	ret = task_set_exception_ports( mach_task_self(),
6796					EXC_MASK_BAD_ACCESS,
6797					exception_port,
6798					EXCEPTION_STATE_IDENTITY,
6799					testFlavor );
6800	/*
6801	 * this test _fails_ if we successfully set the exception port
6802	 * with an invalid thread flavor
6803	 */
6804	if (ret == KERN_SUCCESS) {
6805		task_set_exception_ports( mach_task_self(),
6806					  EXC_MASK_BAD_ACCESS,
6807					  old_except_port, old_behavior, old_flavor );
6808		printf("task_set_exception_ports failed: expected !KERN_SUCCESS for flavor %d\n", testFlavor);
6809		goto test_failed_exit;
6810	}
6811
6812	/*
6813	 * so far, so good: the task_set_exception_ports call failed,
6814	 * so we don't need to reset anything, but we do need to
6815	 * drop our reference to the old exception port we grabbed.
6816	 */
6817	mach_port_deallocate( mach_task_self(), old_except_port );
6818
6819	/*
6820	 * Now try the host exception port
6821	 */
6822	if (__get_except_port(0, &old_except_port, &old_behavior, &old_flavor) < 0)
6823		goto test_failed_exit;
6824
6825	ret = host_set_exception_ports( mach_host_self(),
6826					EXC_MASK_BAD_ACCESS,
6827					exception_port,
6828					EXCEPTION_STATE_IDENTITY,
6829					testFlavor );
6830	/*
6831	 * this test _fails_ if we successfully set the exception port
6832	 * with an invalid thread flavor
6833	 */
6834	if (ret == KERN_SUCCESS) {
6835		host_set_exception_ports( mach_host_self(),
6836					  EXC_MASK_BAD_ACCESS,
6837					  old_except_port, old_behavior, old_flavor );
6838		printf("host_set_exception_ports failed: expected !KERN_SUCCESS for flavor %d\n", testFlavor);
6839		goto test_failed_exit;
6840	}
6841
6842	mach_port_deallocate( mach_task_self(), exception_port );
6843	mach_port_deallocate( mach_task_self(), old_except_port );
6844	return 0;
6845
6846test_failed_exit:
6847	mach_port_deallocate( mach_task_self(), exception_port );
6848	if (old_except_port != MACH_PORT_NULL)
6849		mach_port_deallocate( mach_task_self(), old_except_port );
6850	return -1;
6851}
6852
6853
6854#if TEST_SYSTEM_CALLS
6855
6856/*  **************************************************************************************************************
6857 *	Test xxxxxxxxx system calls.
6858 *  **************************************************************************************************************
6859 */
6860int sample_test( void * the_argp )
6861{
6862	int			my_err;
6863	int			my_fd = -1;
6864	char *		my_pathp = NULL;
6865	kern_return_t           my_kr;
6866
6867        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
6868        if(my_kr != KERN_SUCCESS){
6869                  printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
6870                  goto test_failed_exit;
6871        }
6872
6873	*my_pathp = 0x00;
6874	strcat( my_pathp, &g_target_path[0] );
6875	strcat( my_pathp, "/" );
6876
6877	/* create a test file */
6878	my_err = create_random_name( my_pathp, 1 );
6879	if ( my_err != 0 ) {
6880		goto test_failed_exit;
6881	}
6882
6883	/* add your test code here... */
6884
6885
6886	my_err = 0;
6887	goto test_passed_exit;
6888
6889test_failed_exit:
6890	my_err = -1;
6891
6892test_passed_exit:
6893	if ( my_fd != -1 )
6894		close( my_fd );
6895	if ( my_pathp != NULL ) {
6896		remove( my_pathp );
6897		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
6898	 }
6899	return( my_err );
6900}
6901
6902#endif
6903