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#if !TARGET_OS_EMBEDDED
976
977	/*
978	 * This test makes sure that the access system call does not give the current user extra
979	 * permissions on files the current user does not own. From radar #6725311, this could
980	 * happen when the current user calls access() on a file owned by the current user in
981	 * the same directory as the other files not owned by the current user.
982	 *
983	 * Note: This test expects that the effective uid (euid) is set to root.
984	 *
985	 */
986
987	/* Create a file that root owns  */
988	file_handle = fopen(FILE_NOTME, "w");
989	fclose(file_handle);
990
991	/* Currently running as root (through setreuid manipulation), switch to running as the current user. */
992	euid = geteuid();
993	ruid = getuid();
994	setreuid(ruid, ruid);
995
996	/* Create a file that the current user owns  */
997	file_handle = fopen(FILE_ME, "w");
998	fclose(file_handle);
999
1000	error_occurred = 0;
1001
1002	/* Try to remove the file owned by root (this should fail). */
1003	my_err = unlink(FILE_NOTME);
1004
1005	if (my_err < 0) {
1006		my_err = errno;
1007	}
1008
1009	if (my_err == 0) {
1010		printf("Unresolved: First attempt deleted '" FILE_NOTME "'! \n");
1011		error_occurred = 1;
1012	} else {
1013		printf("Status: First attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
1014
1015		/* Set _DELETE_OK on a file that the current user owns */
1016		access(FILE_ME, _DELETE_OK);
1017
1018		/* Try to remove the file owned by root again (should give us: EPERM [13]) */
1019		my_err = unlink(FILE_NOTME);
1020
1021		if (my_err < 0) {
1022		    my_err = errno;
1023		}
1024
1025		if (my_err == 0) {
1026			printf("Failed: Second attempt deleted '" FILE_NOTME "'!\n");
1027			error_occurred = 1;
1028		} else if (my_err == 13) {
1029			printf("Passed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
1030		} else {
1031			printf("Failed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
1032			error_occurred = 1;
1033		}
1034	}
1035
1036	/* Reset to running as root */
1037	setreuid(ruid, euid);
1038
1039	if(error_occurred == 1) {
1040		goto test_failed_exit;
1041	}
1042
1043#endif
1044
1045	/* end of test*/
1046
1047
1048	/* test fchmod */
1049	my_fd = open( my_pathp, O_RDONLY, 0 );
1050	if ( my_fd == -1 ) {
1051		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1052		printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
1053		goto test_failed_exit;
1054	}
1055
1056	my_err = fchmod( my_fd, S_IRWXU );
1057	if ( my_err == -1 ) {
1058		printf( "fchmod call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1059		goto test_failed_exit;
1060	}
1061
1062	my_err = stat( my_pathp, &my_sb );
1063	if ( my_err != 0 ) {
1064		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1065		goto test_failed_exit;
1066	}
1067
1068	/* verify correct modes are set */
1069	if ( (my_sb.st_mode & (S_IRWXG | S_IRWXO)) != 0 ||
1070		 (my_sb.st_mode & (S_IRWXU)) == 0 ) {
1071		printf( "fchmod call appears to have failed.  stat shows incorrect values in st_mode! \n" );
1072		goto test_failed_exit;
1073	}
1074
1075	my_err = 0;
1076	goto test_passed_exit;
1077
1078test_failed_exit:
1079	my_err = -1;
1080
1081test_passed_exit:
1082	if ( my_fd != -1 )
1083		close( my_fd );
1084	if ( my_pathp != NULL ) {
1085		remove( my_pathp );
1086		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1087	 }
1088	return( my_err );
1089}
1090
1091#if !TARGET_OS_EMBEDDED
1092static bool _prime_groups(void)
1093{
1094	/*
1095	 * prime groups with a known list to ensure consistent test behavior
1096	 */
1097
1098	gid_t	my_exp_groups[] = { getegid(), 20, 61, 12 };
1099	int		my_err;
1100
1101	my_err = setgroups( ( sizeof(my_exp_groups) / sizeof(*my_exp_groups) ), &my_exp_groups[0] );
1102	if ( my_err == -1 ) {
1103		printf( "initial setgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1104		return false;
1105	}
1106
1107	return true;
1108}
1109#endif
1110
1111/*  **************************************************************************************************************
1112 *	Test chown, fchown, lchown, lstat, readlink, symlink system calls.
1113 *  **************************************************************************************************************
1114 */
1115int chown_fchown_lchown_lstat_symlink_test( void * the_argp )
1116{
1117#if !TARGET_OS_EMBEDDED
1118	int			my_err, my_group_count, i;
1119	int			my_fd = -1;
1120	char *			my_pathp = NULL;
1121	char *			my_link_pathp = NULL;
1122	uid_t			my_orig_uid;
1123	gid_t			my_orig_gid, my_new_gid1 = 0, my_new_gid2 = 0;
1124	ssize_t			my_result;
1125	struct stat		my_sb;
1126	gid_t			my_groups[ NGROUPS_MAX ];
1127	char			my_buffer[ 64 ];
1128	kern_return_t           my_kr;
1129
1130        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1131        if(my_kr != KERN_SUCCESS){
1132                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1133                goto test_failed_exit;
1134        }
1135
1136	*my_pathp = 0x00;
1137	strcat( my_pathp, &g_target_path[0] );
1138	strcat( my_pathp, "/" );
1139
1140	/* create a test file */
1141	my_err = create_random_name( my_pathp, 1 );
1142	if ( my_err != 0 ) {
1143		goto test_failed_exit;
1144	}
1145
1146        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_link_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1147        if(my_kr != KERN_SUCCESS){
1148                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1149                goto test_failed_exit;
1150        }
1151
1152	*my_link_pathp = 0x00;
1153	strcat( my_link_pathp, &g_target_path[0] );
1154	strcat( my_link_pathp, "/" );
1155
1156	/* get a test file name for the link */
1157	my_err = create_random_name( my_link_pathp, 0 );
1158	if ( my_err != 0 ) {
1159		goto test_failed_exit;
1160	}
1161
1162	if ( !_prime_groups() ) {
1163		goto test_failed_exit;
1164	}
1165
1166	/* set up by getting a list of groups */
1167	my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
1168
1169	if ( my_group_count == -1 || my_group_count < 1 ) {
1170		printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1171		goto test_failed_exit;
1172	}
1173
1174	my_err = stat( my_pathp, &my_sb );
1175	if ( my_err != 0 ) {
1176		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1177		goto test_failed_exit;
1178	}
1179
1180	/* now change group owner to something other than current value */
1181	my_orig_gid = my_sb.st_gid;
1182	my_orig_uid = my_sb.st_uid;
1183
1184	for ( i = 0; i < my_group_count; i++ ) {
1185		if ( my_orig_gid != my_groups[ i ] ) {
1186			if ( my_new_gid1 == 0 ) {
1187				my_new_gid1 = my_groups[ i ];
1188			}
1189			else {
1190				my_new_gid2 = my_groups[ i ];
1191				break;
1192			}
1193		}
1194	}
1195	if ( i >= my_group_count ) {
1196		printf( "not enough groups to choose from.  st_gid is the same as current groups! \n" );
1197		goto test_failed_exit;
1198	}
1199
1200	my_err = chown( my_pathp, my_orig_uid, my_new_gid1 );
1201	if ( my_err != 0 ) {
1202		printf( "chown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1203		goto test_failed_exit;
1204	}
1205
1206	/* make sure the group owner was changed */
1207	my_err = stat( my_pathp, &my_sb );
1208	if ( my_err != 0 ) {
1209		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1210		goto test_failed_exit;
1211	}
1212	if ( my_sb.st_gid == my_orig_gid ) {
1213		printf( "chown call failed.  st_gid is not correct! \n" );
1214		goto test_failed_exit;
1215	}
1216
1217	/* change group owner back using fchown */
1218	my_fd = open( my_pathp, O_RDWR, 0 );
1219	if ( my_fd == -1 ) {
1220		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1221		printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
1222		goto test_failed_exit;
1223	}
1224
1225	my_err = fchown( my_fd, my_orig_uid, my_new_gid2 );
1226	if ( my_err != 0 ) {
1227		printf( "fchown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1228		goto test_failed_exit;
1229	}
1230
1231	/* make sure the group owner was changed back to the original value */
1232	my_err = stat( my_pathp, &my_sb );
1233	if ( my_err != 0 ) {
1234		printf( "stat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1235		goto test_failed_exit;
1236	}
1237	if ( my_sb.st_gid == my_new_gid1 ) {
1238		printf( "fchown call failed.  st_gid is not correct! \n" );
1239		goto test_failed_exit;
1240	}
1241
1242	/* create a link file and test lchown */
1243	my_err = symlink( my_pathp, my_link_pathp );
1244	if ( my_err != 0 ) {
1245		printf( "symlink call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1246		goto test_failed_exit;
1247	}
1248
1249	my_err = lstat( my_link_pathp, &my_sb );
1250	if ( my_err != 0 ) {
1251		printf( "lstat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1252		goto test_failed_exit;
1253	}
1254
1255	/* now change group owner to something other than current value */
1256	my_orig_gid = my_sb.st_gid;
1257	my_orig_uid = my_sb.st_uid;
1258	my_err = lchown( my_link_pathp, my_orig_uid, my_new_gid1 );
1259	if ( my_err != 0 ) {
1260		printf( "lchown call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1261		goto test_failed_exit;
1262	}
1263
1264	/* make sure the group owner was changed to new value */
1265	my_err = lstat( my_link_pathp, &my_sb );
1266	if ( my_err != 0 ) {
1267		printf( "lstat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1268		goto test_failed_exit;
1269	}
1270	if ( my_sb.st_gid == my_new_gid2 ) {
1271		printf( "lchown call failed.  st_gid is not correct! \n" );
1272		goto test_failed_exit;
1273	}
1274
1275	/* make sure we can read the symlink file */
1276	my_result = readlink( my_link_pathp, &my_buffer[0], sizeof(my_buffer) );
1277	if ( my_result == -1 ) {
1278		printf( "readlink call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1279		goto test_failed_exit;
1280	}
1281	/* make sure we read some data */
1282	if ( my_result < 1 ) {
1283		printf( "readlink failed to read any data. \n" );
1284		goto test_failed_exit;
1285	}
1286
1287	my_err = 0;
1288	goto test_passed_exit;
1289
1290test_failed_exit:
1291	my_err = -1;
1292
1293test_passed_exit:
1294	if ( my_fd != -1 )
1295		close( my_fd );
1296	if ( my_pathp != NULL ) {
1297		remove( my_pathp );
1298		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1299	 }
1300	if ( my_link_pathp != NULL ) {
1301		unlink( my_link_pathp );
1302		vm_deallocate(mach_task_self(), (vm_address_t)my_link_pathp, PATH_MAX);
1303	 }
1304	return( my_err );
1305#else
1306	printf( "\t--> Test not designed for EMBEDDED TARGET\n" );
1307	return 0;
1308#endif
1309}
1310
1311/*  **************************************************************************************************************
1312 *	Test fstatfs, getattrlist, getfsstat, statfs, getfsstat64, statfs64, fstatfs64 system calls.
1313 *  **************************************************************************************************************
1314 */
1315
1316#pragma pack(4)
1317struct vol_attr_buf {
1318	u_int32_t	length;
1319	off_t   	volume_size;
1320	u_int32_t	io_blksize;
1321};
1322#pragma pack()
1323typedef struct vol_attr_buf vol_attr_buf;
1324
1325#define STATFS_TEST_PATH	"/tmp"
1326
1327int fs_stat_tests( void * the_argp )
1328{
1329	int			my_err, my_count, i;
1330	int			my_buffer_size, my_buffer64_size;
1331	int			my_fd = -1;
1332	int			is_ufs = 0;
1333	long		my_io_size;
1334	fsid_t		my_fsid;
1335	struct attrlist 	my_attrlist;
1336	vol_attr_buf        my_attr_buf;
1337	void *				my_bufferp = NULL;
1338	struct statfs *		my_statfsp;
1339	kern_return_t       my_kr;
1340
1341#if !TARGET_OS_EMBEDDED
1342	void * my_buffer64p = NULL;
1343	struct statfs64 *	my_statfs64p;
1344
1345	my_buffer64_size = (sizeof(struct statfs64) * 10);
1346
1347	my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_buffer64p, my_buffer64_size, VM_FLAGS_ANYWHERE);
1348	if(my_kr != KERN_SUCCESS){
1349	  printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1350	  goto test_failed_exit;
1351	}
1352
1353#endif
1354	my_buffer_size = (sizeof(struct statfs) * 10);
1355
1356	my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_bufferp, my_buffer_size, VM_FLAGS_ANYWHERE);
1357        if(my_kr != KERN_SUCCESS){
1358                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1359                goto test_failed_exit;
1360        }
1361
1362	my_statfsp = (struct statfs *) my_bufferp;
1363	my_err = statfs( STATFS_TEST_PATH, my_statfsp );
1364	if ( my_err == -1 ) {
1365		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1366		goto test_failed_exit;
1367	}
1368	if ( memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ) {
1369		is_ufs = 1;
1370	}
1371
1372	my_count = getfsstat( (struct statfs *)my_bufferp, my_buffer_size, MNT_NOWAIT );
1373	if ( my_count == -1 ) {
1374		printf( "getfsstat call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1375		goto test_failed_exit;
1376	}
1377
1378	/* validate results */
1379	my_statfsp = (struct statfs *) my_bufferp;
1380	for ( i = 0; i < my_count; i++, my_statfsp++ ) {
1381		if ( memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
1382			 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ||
1383			 memcmp( &my_statfsp->f_fstypename[0], "devfs", 5 ) == 0 ||
1384			 memcmp( &my_statfsp->f_fstypename[0], "volfs", 5 ) == 0 ) {
1385			/* found a valid entry */
1386			break;
1387		}
1388	}
1389	if ( i >= my_count ) {
1390		printf( "getfsstat call failed.  could not find valid f_fstypename! \n" );
1391		goto test_failed_exit;
1392	}
1393
1394#if !TARGET_OS_EMBEDDED
1395	/* now try statfs64 */
1396	my_statfs64p = (struct statfs64 *) my_buffer64p;
1397	my_err = statfs64( STATFS_TEST_PATH, my_statfs64p );
1398	if ( my_err == -1 ) {
1399		printf( "statfs64 call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1400		goto test_failed_exit;
1401	}
1402	if ( my_statfs64p->f_fsid.val[0] != my_statfsp->f_fsid.val[0] ||
1403		 my_statfs64p->f_fsid.val[1] != my_statfsp->f_fsid.val[1] ) {
1404		printf( "statfs64 call failed.  wrong f_fsid! \n" );
1405		goto test_failed_exit;
1406	}
1407
1408	my_count = getfsstat64( (struct statfs64 *)my_buffer64p, my_buffer64_size, MNT_NOWAIT );
1409	if ( my_count == -1 ) {
1410		printf( "getfsstat64 call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1411		goto test_failed_exit;
1412	}
1413
1414	/* validate results */
1415	my_statfs64p = (struct statfs64 *) my_buffer64p;
1416	for ( i = 0; i < my_count; i++, my_statfs64p++ ) {
1417		if ( memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 ||
1418			 memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0 ||
1419			 memcmp( &my_statfs64p->f_fstypename[0], "devfs", 5 ) == 0 ||
1420			 memcmp( &my_statfs64p->f_fstypename[0], "volfs", 5 ) == 0 ) {
1421			/* found a valid entry */
1422			break;
1423		}
1424	}
1425	if ( i >= my_count ) {
1426		printf( "getfsstat64 call failed.  could not find valid f_fstypename! \n" );
1427		goto test_failed_exit;
1428	}
1429#endif
1430
1431	/* set up to validate results via multiple sources.  we use getattrlist to get volume
1432	 * related attributes to verify against results from fstatfs and statfs - but only if
1433	 * we are not targeting ufs volume since it doesn't support getattr calls
1434	 */
1435	if ( is_ufs == 0 ) {
1436		memset( &my_attrlist, 0, sizeof(my_attrlist) );
1437		my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
1438		my_attrlist.volattr = (ATTR_VOL_SIZE | ATTR_VOL_IOBLOCKSIZE);
1439		my_err = getattrlist( "/", &my_attrlist, &my_attr_buf, sizeof(my_attr_buf), 0 );
1440		if ( my_err != 0 ) {
1441			printf( "getattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1442			goto test_failed_exit;
1443		}
1444	}
1445
1446	/* open to use as test file for fstatfs */
1447 	my_fd = open( STATFS_TEST_PATH, O_RDONLY, 0 );
1448	if ( my_fd == -1 ) {
1449		printf( "open call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1450		goto test_failed_exit;
1451	}
1452
1453#if !TARGET_OS_EMBEDDED
1454	/* testing fstatfs64 */
1455	my_statfs64p = (struct statfs64 *) my_buffer64p;
1456	my_err = fstatfs64( my_fd, my_statfs64p );
1457	if ( my_err == -1 ) {
1458		printf( "fstatfs64 call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1459		goto test_failed_exit;
1460	}
1461
1462	/* validate results - assumes we only boot from hfs or ufs */
1463	if ( !(memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 ||
1464		   memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0) ) {
1465		printf( "fstatfs64 call failed.  could not find valid f_fstypename! \n" );
1466		goto test_failed_exit;
1467	}
1468#endif
1469
1470	/* testing fstatfs */
1471	my_statfsp = (struct statfs *) my_bufferp;
1472	my_err = fstatfs( my_fd, my_statfsp );
1473	if ( my_err == -1 ) {
1474		printf( "fstatfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1475		goto test_failed_exit;
1476	}
1477
1478	/* validate results */
1479	if ( !(memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
1480		   memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0) ) {
1481		printf( "fstatfs call failed.  could not find valid f_fstypename! \n" );
1482		goto test_failed_exit;
1483	}
1484	my_io_size = my_statfsp->f_iosize;
1485	my_fsid = my_statfsp->f_fsid;
1486	if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
1487		printf( "fstatfs and getattrlist results do not match for volume block size  \n" );
1488		goto test_failed_exit;
1489	}
1490
1491	/* try again with statfs */
1492	my_err = statfs( STATFS_TEST_PATH , my_statfsp );
1493	if ( my_err == -1 ) {
1494		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1495		goto test_failed_exit;
1496	}
1497
1498	/* validate results */
1499	if ( my_io_size != my_statfsp->f_iosize || my_fsid.val[0] != my_statfsp->f_fsid.val[0] ||
1500		 my_fsid.val[1] != my_statfsp->f_fsid.val[1] ) {
1501		printf( "statfs call failed.  wrong f_iosize or f_fsid! \n" );
1502		goto test_failed_exit;
1503	}
1504	if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
1505		printf( "statfs and getattrlist results do not match for volume block size  \n" );
1506		goto test_failed_exit;
1507	}
1508
1509	my_err = 0;
1510	goto test_passed_exit;
1511
1512test_failed_exit:
1513	my_err = -1;
1514
1515test_passed_exit:
1516	if ( my_fd != -1 )
1517		close( my_fd );
1518	if ( my_bufferp != NULL ) {
1519		vm_deallocate(mach_task_self(), (vm_address_t)my_bufferp, my_buffer_size);
1520	 }
1521#if !TARGET_OS_EMBEDDED
1522	 if ( my_buffer64p != NULL ) {
1523		vm_deallocate(mach_task_self(), (vm_address_t)my_buffer64p, my_buffer64_size);
1524	 }
1525#endif
1526
1527	return( my_err );
1528}
1529
1530/*  **************************************************************************************************************
1531 *	Test getpid, getppid, and pipe system calls.
1532 *  **************************************************************************************************************
1533 */
1534int getpid_getppid_pipe_test( void * the_argp )
1535{
1536	int			my_err, my_status;
1537	pid_t		my_pid, my_wait_pid;
1538	ssize_t		my_count;
1539	int			my_fildes[2] = {-1, -1};
1540	off_t		my_current_offset;
1541	char		my_pid_string[64];
1542
1543	my_err = pipe( &my_fildes[0] );
1544	if ( my_err != 0 ) {
1545		printf( "pipe call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1546		goto test_failed_exit;
1547	}
1548
1549	/* make sure we can't seek on a pipe */
1550	my_current_offset = lseek( my_fildes[0], 0, SEEK_CUR );
1551	if ( my_current_offset != -1 ) {
1552		printf( "lseek on pipe should fail but did not \n" );
1553		goto test_failed_exit;
1554	}
1555
1556	/* fork here and use pipe to communicate */
1557	my_pid = fork( );
1558	if ( my_pid == -1 ) {
1559		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
1560		goto test_failed_exit;
1561	}
1562	else if ( my_pid == 0 ) {
1563		/* child process */
1564		unsigned long	my_ppid;
1565		char			my_buffer[64];
1566
1567		close( my_fildes[1] ); /* close write end of pipe */
1568		my_fildes[1] = -1;
1569
1570		/* get the parent's pid using getppid and from the parent (using getpid in porent) */
1571		my_count = read( my_fildes[0], &my_buffer[0], sizeof(my_buffer) );
1572		if ( my_count == -1 ) {
1573			printf( "read from pipe failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1574			exit(-1);
1575		}
1576
1577		/* parent wrote (to our pipe) its pid as character string */
1578		my_ppid = strtoul( &my_buffer[0], NULL, 10 );
1579		if ( my_ppid == 0 ) {
1580			printf( "strtoul failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1581			exit(-1);
1582		}
1583
1584		if ( getppid( ) != my_ppid ) {
1585			printf( "getppid failed.  pid we got from parent does not match getppid result. \n" );
1586			exit(-1);
1587		}
1588		exit(0);
1589	}
1590
1591	/* parent process - get our pid using getpid and send it to child for verification */
1592	close( my_fildes[0] ); /* close read end of pipe */
1593	my_fildes[0] = -1;
1594
1595	sprintf( &my_pid_string[0], "%d\n", getpid( ) );
1596
1597	my_count = write( my_fildes[1], &my_pid_string[0], sizeof(my_pid_string) );
1598	if ( my_count == -1 ) {
1599		printf( "write to pipe failed.  got errno %d - %s. \n", errno, strerror( errno ) );
1600		goto test_failed_exit;
1601	}
1602
1603	/* wait for child to exit */
1604	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
1605	if ( my_wait_pid == -1 ) {
1606		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
1607		goto test_failed_exit;
1608	}
1609
1610	/* wait4 should return our child's pid when it exits */
1611	if ( my_wait_pid != my_pid ) {
1612		printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
1613		goto test_failed_exit;
1614	}
1615
1616	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
1617		printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
1618		goto test_failed_exit;
1619	}
1620
1621	my_err = 0;
1622	goto test_passed_exit;
1623
1624test_failed_exit:
1625	my_err = -1;
1626
1627test_passed_exit:
1628	if ( my_fildes[0] != -1 )
1629		close( my_fildes[0] );
1630	if ( my_fildes[1] != -1 )
1631		close( my_fildes[1] );
1632	return( my_err );
1633}
1634
1635
1636/*  **************************************************************************************************************
1637 *	Test getauid, gettid, getuid, geteuid, issetugid, setaudit_addr, seteuid, settid, settid_with_pid, setuid system calls.
1638 *  **************************************************************************************************************
1639 */
1640int uid_tests( void * the_argp )
1641{
1642	int			my_err, my_status;
1643	pid_t		my_pid, my_wait_pid;
1644
1645	if ( g_skip_setuid_tests != 0 ) {
1646		printf("\t skipping this test \n");
1647		my_err = 0;
1648		goto test_passed_exit;
1649	}
1650
1651	/* test issetugid - should return 1 when not root and 0 when root
1652	 * Figuring out setugid will not work in single-user mode; skip
1653	 * this test in that case.
1654	 */
1655	if (!g_is_single_user) {
1656		my_err = issetugid( );
1657		if ( getuid( ) == 0 ) {
1658			if ( my_err == 1 ) {
1659				printf( "issetugid should return false \n" );
1660				goto test_failed_exit;
1661			}
1662		}
1663		else {
1664			if ( my_err == 0 ) {
1665				printf( "issetugid should return true \n" );
1666				goto test_failed_exit;
1667			}
1668		}
1669	}
1670
1671	/*
1672	 * fork here and do the setuid work in the child
1673	 */
1674	my_pid = fork( );
1675	if ( my_pid == -1 ) {
1676		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
1677		goto test_failed_exit;
1678	}
1679	else if ( my_pid == 0 ) {
1680		/*
1681		 * child process
1682		 */
1683		uid_t			my_ruid, my_euid;
1684		uid_t			my_uid, my_temp_uid;
1685		gid_t			my_gid, my_temp_gid;
1686		auditinfo_addr_t	my_aia;
1687
1688		my_ruid = getuid( );
1689		my_euid = geteuid( );
1690		if ( my_ruid == my_euid ) {
1691			exit( 0 );
1692		}
1693
1694		/* Test getauid, gettid, setaudit_addr, settid, settid_with_pid */
1695		/* get our current uid and gid for comparison later */
1696		my_uid = getuid( );
1697		my_gid = getgid( );
1698
1699		my_err = syscall( SYS_settid, 4444, 5555 );
1700		//my_err = settid( 4444, 5555 );
1701		if (my_err != 0) {
1702			printf( "settid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1703			exit( -1 );
1704		}
1705
1706		my_err = syscall( SYS_gettid, &my_temp_uid, &my_temp_gid );
1707		//my_err = gettid( &my_temp_uid, &my_temp_gid );
1708		if (my_err != 0) {
1709			printf( "gettid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1710			exit( -1 );
1711		}
1712		if (my_temp_uid != 4444) {
1713			printf("get / settid test failed - wrong uid was set - %d \n", my_temp_uid);
1714			exit( -1 );
1715		}
1716		if (my_temp_gid != 5555) {
1717			printf("get / settid test failed - wrong gid was set - %d \n", my_temp_gid);
1718			exit( -1 );
1719		}
1720
1721		/* resume original identity */
1722		my_err = syscall( SYS_settid, KAUTH_UID_NONE, KAUTH_GID_NONE );
1723		//my_err = settid( KAUTH_UID_NONE, KAUTH_GID_NONE );
1724		if (my_err != 0) {
1725			printf( "settid revert - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1726			exit( -1 );
1727		}
1728
1729		/* values should be returned to original settings */
1730		my_temp_uid = getuid( );
1731		if (my_temp_uid == 4444) {
1732			printf("test failed - wrong uid was set - %d \n", my_temp_uid);
1733			exit( -1 );
1734		}
1735		my_temp_gid = getgid( );
1736		if (my_temp_gid == 5555) {
1737			printf("test failed - wrong gid was set - %d \n", my_temp_gid);
1738			exit( -1 );
1739		}
1740
1741		/*
1742		 * Assume the identity of our parent.
1743		 */
1744		my_err = syscall( SYS_settid_with_pid, getppid( ), 1 );
1745		//my_err = settid_with_pid, my_target_pid, 1 );
1746		if (my_err != 0) {
1747			printf( "settid_with_pid assume - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1748			exit( -1 );
1749		}
1750
1751		/*
1752		 * Resume our identity.
1753		 */
1754		my_err = syscall( SYS_settid_with_pid, 0, 0 );
1755		//my_err = settid_with_pid( my_target_pid, 0 );
1756		if (my_err != 0) {
1757			printf( "settid_with_pid resume - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1758			exit( -1 );
1759		}
1760
1761		/*
1762		 * test to make sure setaudit_addr doesn't cause audit info to get lost from
1763		 * the credential.
1764		 */
1765		bzero( &my_aia, sizeof(my_aia) );
1766		my_aia.ai_auid = 442344;
1767		my_aia.ai_asid = AU_ASSIGN_ASID;
1768		my_aia.ai_termid.at_type = AU_IPv4;
1769		my_err = setaudit_addr( &my_aia, sizeof(my_aia) );
1770		if (my_err != 0) {
1771			printf( "setaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1772			exit( -1 );
1773		}
1774
1775		my_aia.ai_auid = 0;
1776		my_err = getaudit_addr( &my_aia, sizeof(my_aia) );
1777		if (my_err != 0) {
1778			printf( "getaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1779			exit( -1 );
1780		}
1781		//printf("new audit ID is %d \n", my_aia.ai_auid);
1782
1783		if (my_aia.ai_auid != 442344) {
1784			printf("test failed - wrong audit ID was set - %d \n", my_aia.ai_auid);
1785			exit( -1 );
1786		}
1787
1788		/* change real uid and effective uid to current euid */
1789		my_err = setuid( my_euid );
1790		if ( my_err == -1 ) {
1791			printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1792			exit( -1 );
1793		}
1794		if ( getuid( ) != my_euid ) {
1795			printf( "setuid call failed to set the real uid \n" );
1796			exit( -1 );
1797		}
1798
1799		/* change effective uid to current euid - really a NOP */
1800		my_err = seteuid( my_euid );
1801		if ( my_err == -1 ) {
1802			printf( "seteuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1803			exit( -1 );
1804		}
1805		if ( geteuid( ) != my_euid ) {
1806			printf( "seteuid call failed to set the original euid \n" );
1807			exit( -1 );
1808		}
1809
1810		/* change real uid and effective uid to original real uid */
1811		my_err = setuid( my_ruid );
1812		if ( my_err == -1 ) {
1813			printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1814			exit( -1 );
1815		}
1816		if ( getuid( ) != my_ruid ) {
1817			printf( "setuid call failed to set the real uid \n" );
1818			exit( -1 );
1819		}
1820
1821		exit(0);
1822	}
1823
1824	/*
1825	 * parent process -
1826	 * wait for child to exit
1827	 */
1828	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
1829	if ( my_wait_pid == -1 ) {
1830		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
1831		goto test_failed_exit;
1832	}
1833
1834	/* wait4 should return our child's pid when it exits */
1835	if ( my_wait_pid != my_pid ) {
1836		printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
1837		goto test_failed_exit;
1838	}
1839
1840	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
1841		printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
1842		goto test_failed_exit;
1843	}
1844
1845	my_err = 0;
1846	goto test_passed_exit;
1847
1848test_failed_exit:
1849	my_err = -1;
1850
1851test_passed_exit:
1852	return( my_err );
1853}
1854
1855/*  **************************************************************************************************************
1856 *	Test mknod, sync system calls.
1857 *  **************************************************************************************************************
1858 */
1859int mknod_sync_test( void * the_argp )
1860{
1861	int			my_err;
1862	char *	my_pathp =      NULL;
1863	kern_return_t           my_kr;
1864
1865	if ( g_skip_setuid_tests != 0 ) {
1866		printf("\t skipping this test \n");
1867		my_err = 0;
1868		goto test_passed_exit;
1869	}
1870
1871        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1872        if(my_kr != KERN_SUCCESS){
1873                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1874                goto test_failed_exit;
1875        }
1876
1877	*my_pathp = 0x00;
1878	strcat( my_pathp, "/dev/" );
1879
1880	/* get a unique name for our test file */
1881	my_err = create_random_name( my_pathp, 0 );
1882	if ( my_err != 0 ) {
1883		goto test_failed_exit;
1884	}
1885
1886	my_err = mknod( my_pathp, (S_IFCHR | S_IRWXU), 0 );
1887	if ( my_err == -1 ) {
1888		printf( "mknod failed with errno %d - %s \n", errno, strerror( errno ) );
1889		printf( "path \"%s\" \n", my_pathp );
1890		goto test_failed_exit;
1891	}
1892
1893	/* not really sure what to do with sync call test */
1894	sync( );
1895	my_err = 0;
1896	goto test_passed_exit;
1897
1898test_failed_exit:
1899	my_err = -1;
1900
1901test_passed_exit:
1902	if ( my_pathp != NULL ) {
1903		remove( my_pathp );
1904		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1905	 }
1906	return( my_err );
1907}
1908
1909/*  **************************************************************************************************************
1910 *	Test chflags, fchflags system calls.
1911 *  **************************************************************************************************************
1912 */
1913int chflags_fchflags_test( void * the_argp )
1914{
1915	int				my_err;
1916	int				my_fd = -1;
1917	u_int			my_flags;
1918	char *			my_pathp = NULL;
1919	struct stat		my_sb;
1920	kern_return_t           my_kr;
1921
1922        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1923        if(my_kr != KERN_SUCCESS){
1924                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1925                goto test_failed_exit;
1926        }
1927
1928	*my_pathp = 0x00;
1929	strcat( my_pathp, &g_target_path[0] );
1930	strcat( my_pathp, "/" );
1931
1932	/* create a test file */
1933	my_err = create_random_name( my_pathp, 1 );
1934	if ( my_err != 0 ) {
1935		goto test_failed_exit;
1936	}
1937
1938	/* make test file unchangable */
1939	my_err = stat( my_pathp, &my_sb );
1940	if ( my_err != 0 ) {
1941		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1942		goto test_failed_exit;
1943	}
1944
1945	my_flags = (my_sb.st_flags | UF_IMMUTABLE);
1946	my_err = chflags( my_pathp, my_flags );
1947	if ( my_err != 0 ) {
1948		printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1949		goto test_failed_exit;
1950	}
1951
1952	/* should fail with EPERM since we cannot change the file now */
1953	my_fd = open( my_pathp, O_RDWR, 0 );
1954	if ( my_fd == -1 && errno != EPERM ) {
1955		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1956		printf( "open failed with wrong error - should be EPERM \n" );
1957		goto test_failed_exit;
1958	}
1959
1960	/* this open should work OK */
1961	my_fd = open( my_pathp, O_RDONLY, 0 );
1962	if ( my_fd == -1 ) {
1963		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1964		goto test_failed_exit;
1965	}
1966
1967	my_err = stat( my_pathp, &my_sb );
1968	if ( my_err != 0 ) {
1969		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1970		goto test_failed_exit;
1971	}
1972
1973	my_flags = (my_sb.st_flags & ~UF_IMMUTABLE);
1974	my_err = fchflags( my_fd, my_flags );
1975	if ( my_err != 0 ) {
1976		printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1977		goto test_failed_exit;
1978	}
1979
1980	close( my_fd );
1981	my_fd = -1;
1982
1983	/* should now work */
1984	my_fd = open( my_pathp, O_RDWR, 0 );
1985	if ( my_fd == -1 ) {
1986		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1987		goto test_failed_exit;
1988	}
1989
1990	my_err = 0;
1991	goto test_passed_exit;
1992
1993test_failed_exit:
1994	my_err = -1;
1995
1996test_passed_exit:
1997	if ( my_fd != -1 )
1998		close( my_fd );
1999	if ( my_pathp != NULL ) {
2000		remove( my_pathp );
2001		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2002	 }
2003	return( my_err );
2004}
2005
2006
2007/*  **************************************************************************************************************
2008 *	Test kill, vfork, execve system calls.
2009 *  **************************************************************************************************************
2010 */
2011/*  There are many new exec() situations to test now that 64-bit is in. These extra tests are in response to
2012 * rdar://4606399 and rdar://4607285. It should cover every permutation of the following variables.
2013 *
2014 *  - Current Process "Bitness": 			64 or 32
2015 *  - exec()'ed process "bitness": 			64 or 32
2016 *  	(if 64 bit, size of page zero:)			(4GB or 4KB)
2017 *  - Parent Process "Bitness":				64 or 32
2018
2019 *  Test to make sure certain inheritance properties of fork()'ed children
2020 * are correctly set.
2021 *  1. 64 bit process forking() 64-bit child, child execing() 64-bit file (4GB pagezero)
2022 *  2. 64 bit process forking() 64-bit child, child execing() 64-bit file (4KB pagezero)
2023 *  3. 64 bit process forking() 64-bit child, child execing() 32-bit file
2024 *  4. 32 bit process forking() 32-bit child, child execing() 32-bit file
2025 *  5. 32 bit process forking() 32-bit child, child execing() 64 bit file (4GB pagezero)
2026 *  6. 32 bit process forking() 32-bit child, child execing() 64 bit file (4KB pagezero)
2027 *
2028 */
2029
2030
2031int execve_kill_vfork_test( void * the_argp )
2032{
2033	int	my_err, my_status;
2034	pid_t	my_pid, my_wait_pid;
2035	char *	errmsg = NULL;
2036	char * argvs[2] = {"", NULL};
2037	int bits = get_bits();		/* Gets actual processor bit-ness. */
2038
2039	if (bits != 32 && bits != 64) {
2040		printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits());
2041		return(-1);
2042	}
2043
2044	if (get_architecture() == -1) {
2045		errmsg = "get_architecture() could not determine the CPU architecture.\n";
2046		goto test_failed_exit;
2047	}
2048
2049	if (get_architecture() == INTEL) {
2050		struct stat sb;
2051
2052		if (bits == 64 && sizeof(long) == 8) {
2053			/*
2054			 * Running on x86_64 hardware and running in 64-bit mode.
2055			 * Check cases 1, 2, 3 and fork a child to check 4, 5, 6.
2056			 */
2057			errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4G pagezero.\n";
2058			argvs[0] = "sleep-x86_64-4G";
2059			if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 1))		goto test_failed_exit;
2060
2061			errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4K Pagezero.\n";
2062			argvs[0] = "sleep-x86_64-4K";
2063			if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 1))		goto test_failed_exit;
2064
2065			errmsg = "execve failed: from x64_64 forking and exec()ing 32-bit i386 process.\n";
2066			argvs[0] = "sleep-i386";
2067			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1))		goto test_failed_exit;
2068
2069			/* Fork off a helper process and load a 32-bit program in it to test 32->64 bit exec(). */
2070			errmsg = "execve failed to exec the helper process.\n";
2071			argvs[0] = "launch-i386";
2072			if (do_execve_test("helpers/launch-i386", argvs, NULL, 1) != 0)		goto test_failed_exit;
2073
2074			/* Test posix_spawn for i386, x86_64 (should succeed) */
2075			errmsg = NULL;
2076			if (do_spawn_test(CPU_TYPE_I386, 0))
2077				goto test_failed_exit;
2078			if (do_spawn_test(CPU_TYPE_X86_64, 0))
2079				goto test_failed_exit;
2080		}
2081		else if (bits == 64 && sizeof(long) == 4) {
2082			/*
2083			 * Running on x86_64 hardware, but actually running in 32-bit mode.
2084			 * Check cases 4, 5, 6 and fork a child to check 1, 2, 3.
2085			 */
2086			errmsg = "execve failed: from i386 forking and exec()ing i386 process.\n";
2087			argvs[0] = "sleep-i386";
2088			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 0))		goto test_failed_exit;
2089
2090			errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4G pagezero.\n";
2091			argvs[0] = "sleep-x86_64-4G";
2092			if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 0))		goto test_failed_exit;
2093
2094			errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4K pagezero.\n";
2095			argvs[0] = "sleep-x86_64-4K";
2096			if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 0))		goto test_failed_exit;
2097
2098			/* Fork off a helper process and load a 64-bit program in it to test 64->32 bit exec(). */
2099			errmsg = "execve failed to exec the helper process.\n";
2100			argvs[0] = "launch-x86_64";
2101			if (do_execve_test("helpers/launch-x86_64", argvs, NULL, 1) != 0)	goto test_failed_exit;
2102
2103			/* Test posix_spawn for i386, x86_64 (should succeed) */
2104			errmsg = NULL;
2105			if (do_spawn_test(CPU_TYPE_I386, 0))
2106				goto test_failed_exit;
2107			if (do_spawn_test(CPU_TYPE_X86_64, 0))
2108				goto test_failed_exit;
2109		}
2110		else if (bits == 32) {
2111			/* Running on i386 hardware. Check cases 4. */
2112			errmsg = "execve failed: from i386 forking and exec()ing 32-bit i386 process.\n";
2113			argvs[0] = "sleep-i386";
2114			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) 		goto test_failed_exit;
2115
2116			/* Test posix_spawn for x86_64 (should fail), i386 (should succeed) */
2117			errmsg = NULL;
2118			if (do_spawn_test(CPU_TYPE_X86_64, 1))
2119				goto test_failed_exit;
2120			if (do_spawn_test(CPU_TYPE_I386, 0))
2121				goto test_failed_exit;
2122		}
2123	}else if(get_architecture() == ARM) {
2124		if	(bits == 32) {
2125
2126			/* Running on arm hardware. Check cases 2. */
2127			errmsg = "execve failed: from arm forking and exec()ing 32-bit arm process.\n";
2128			argvs[0] = "sleep-arm";
2129			if (do_execve_test("helpers/sleep-arm", argvs, NULL, 1))
2130				goto test_failed_exit;
2131
2132			/* Test posix_spawn for arm (should succeed) */
2133			errmsg = NULL;
2134			if (do_spawn_test(CPU_TYPE_ARM, 0))
2135				goto test_failed_exit;
2136		}
2137	}
2138	else {
2139		/* Just in case someone decides we need more architectures in the future */
2140		printf("get_architecture() returned unknown architecture");
2141		return(-1);
2142	}
2143
2144	return 0;
2145
2146test_failed_exit:
2147	if (errmsg)
2148		printf("%s", errmsg);
2149	return -1;
2150}
2151
2152
2153/*  **************************************************************************************************************
2154 *	Test getegid, getgid, getgroups, setegid, setgid, setgroups system calls.
2155 *  **************************************************************************************************************
2156 */
2157int groups_test( void * the_argp )
2158{
2159#if !TARGET_OS_EMBEDDED
2160	int			my_err, i;
2161	int			my_group_count, my_orig_group_count;
2162	gid_t		my_real_gid;
2163	gid_t		my_effective_gid;
2164	gid_t		my_removed_gid;
2165	gid_t		my_new_gid;
2166	gid_t		my_groups[ NGROUPS_MAX ];
2167
2168	if ( g_skip_setuid_tests != 0 ) {
2169		printf("\t skipping this test \n");
2170		my_err = 0;
2171		goto test_passed_exit;
2172	}
2173
2174	my_real_gid = getgid( );
2175	my_effective_gid = getegid( );
2176
2177	if ( !_prime_groups() ) {
2178		goto test_failed_exit;
2179	}
2180
2181	/* start by getting list of groups the current user belongs to */
2182	my_orig_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
2183
2184	if ( my_orig_group_count == -1 || my_orig_group_count < 1 ) {
2185		printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2186		goto test_failed_exit;
2187	}
2188
2189	/* make sure real and effective gids are correct */
2190	for ( i = 0; i < my_orig_group_count; i++ ) {
2191		if ( my_groups[i] == my_real_gid )
2192			break;
2193	}
2194	if ( i >= my_orig_group_count ) {
2195		printf( "getgid or getgroups call failed.  could not find real gid in list of groups. \n" );
2196		goto test_failed_exit;
2197	}
2198	for ( i = 0; i < my_orig_group_count; i++ ) {
2199		if ( my_groups[i] == my_effective_gid )
2200			break;
2201	}
2202	if ( i >= my_orig_group_count ) {
2203		printf( "getegid or getgroups call failed.  could not find effective gid in list of groups. \n" );
2204		goto test_failed_exit;
2205	}
2206
2207	/* remove the last group */
2208	my_removed_gid = my_groups[ (my_orig_group_count - 1) ];
2209	my_err = setgroups( (my_orig_group_count - 1), &my_groups[0] );
2210	if ( my_err == -1 ) {
2211		printf( "setgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2212		goto test_failed_exit;
2213	}
2214
2215	my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
2216
2217	if ( my_group_count == -1 || my_group_count < 1 ) {
2218		printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2219		goto test_failed_exit;
2220	}
2221
2222	/* make sure setgroups dropped one */
2223	if ( my_orig_group_count <= my_group_count ) {
2224		printf( "setgroups call failed.  current group count is too high. \n" );
2225		goto test_failed_exit;
2226	}
2227
2228	/* now put removed gid back */
2229	my_groups[ (my_orig_group_count - 1) ] = my_removed_gid;
2230	my_err = setgroups( my_orig_group_count, &my_groups[0] );
2231	if ( my_err == -1 ) {
2232		printf( "setgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2233		goto test_failed_exit;
2234	}
2235
2236	/* find a group to change real and effective gid to then do it */
2237	my_new_gid = -1;
2238	for ( i = 0; i < my_orig_group_count; i++ ) {
2239		if ( my_groups[i] == my_effective_gid || my_groups[i] == my_real_gid )
2240			continue;
2241		my_new_gid = my_groups[i];
2242	}
2243
2244	if ( my_new_gid == -1 ) {
2245		printf( "could not find a gid to switch to. \n" );
2246		goto test_failed_exit;
2247	}
2248
2249	/* test setegid */
2250	my_err = setegid( my_new_gid );
2251	if ( my_err == -1 ) {
2252		printf( "setegid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2253		goto test_failed_exit;
2254	}
2255	/* verify it changed */
2256	if ( getegid( ) != my_new_gid ) {
2257		printf( "setegid failed to change the effective gid. \n" );
2258		goto test_failed_exit;
2259	}
2260	/* change it back to original value */
2261	my_err = setegid( my_effective_gid );
2262	if ( my_err == -1 ) {
2263		printf( "setegid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2264		goto test_failed_exit;
2265	}
2266
2267	/* test setgid */
2268	my_err = setgid( my_new_gid );
2269	if ( my_err == -1 ) {
2270		printf( "setgid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2271		goto test_failed_exit;
2272	}
2273	/* verify it changed */
2274	if ( getgid( ) != my_new_gid ) {
2275		printf( "setgid failed to change the real gid. \n" );
2276		goto test_failed_exit;
2277	}
2278	/* change it back to original value */
2279	my_err = setgid( my_real_gid );
2280	if ( my_err == -1 ) {
2281		printf( "setegid call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2282		goto test_failed_exit;
2283	}
2284
2285	my_err = 0;
2286	goto test_passed_exit;
2287
2288test_failed_exit:
2289	my_err = -1;
2290
2291test_passed_exit:
2292	return( my_err );
2293#else
2294	printf( "\t--> Test not designed for EMBEDDED TARGET\n" );
2295	return 0;
2296#endif
2297}
2298
2299
2300/*  **************************************************************************************************************
2301 *	Test dup, dup2, getdtablesize system calls.
2302 *  **************************************************************************************************************
2303 */
2304int dup_test( void * the_argp )
2305{
2306	int			my_err;
2307	int			my_fd = -1;
2308	int			my_newfd = -1;
2309	int			my_table_size, my_loop_counter = 0;
2310	char *		my_pathp = NULL;
2311	ssize_t		my_count;
2312	char		my_buffer[64];
2313	kern_return_t           my_kr;
2314
2315        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2316        if(my_kr != KERN_SUCCESS){
2317                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2318                goto test_failed_exit;
2319        }
2320
2321	*my_pathp = 0x00;
2322	strcat( my_pathp, &g_target_path[0] );
2323	strcat( my_pathp, "/" );
2324
2325	/* create a test file */
2326	my_err = create_random_name( my_pathp, 1 );
2327	if ( my_err != 0 ) {
2328		goto test_failed_exit;
2329	}
2330
2331	/* test dup, dup2, getdtablesize */
2332	my_table_size = getdtablesize( );
2333	if ( my_table_size < 20 ) {
2334		printf( "getdtablesize should return at least 20, returned %d \n", my_table_size );
2335		goto test_failed_exit;
2336	}
2337
2338	my_fd = open( my_pathp, O_RDWR, 0 );
2339	if ( my_fd == -1 ) {
2340		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2341		goto test_failed_exit;
2342	}
2343
2344	my_newfd = dup( my_fd );
2345	if ( my_newfd == -1 ) {
2346		printf( "dup call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2347		goto test_failed_exit;
2348	}
2349
2350redo:
2351	/* now write somne data to the orginal and new fd */
2352	/* make sure test file is empty */
2353	my_err = ftruncate( my_fd, 0 );
2354	if ( my_err == -1 ) {
2355		printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2356		goto test_failed_exit;
2357	}
2358
2359	lseek( my_fd, 0, SEEK_SET );
2360	my_count = write( my_fd, "aa", 2 );
2361	if ( my_count == -1 ) {
2362		printf( "write call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2363		goto test_failed_exit;
2364	}
2365
2366	my_count = write( my_newfd, "xx", 2 );
2367	if ( my_count == -1 ) {
2368		printf( "write call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
2369		goto test_failed_exit;
2370	}
2371
2372	/* now read it back and make sure data is correct */
2373	lseek( my_fd, 0, SEEK_SET );
2374	my_count = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
2375	if ( my_count == -1 ) {
2376		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2377		goto test_failed_exit;
2378	}
2379	if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) {
2380		printf( "wrong data in test file. \n" );
2381		goto test_failed_exit;
2382	}
2383
2384	bzero( &my_buffer[0], sizeof(my_buffer) );
2385	lseek( my_newfd, 0, SEEK_SET );
2386	my_count = read( my_newfd, &my_buffer[0], sizeof(my_buffer) );
2387	if ( my_count == -1 ) {
2388		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2389		goto test_failed_exit;
2390	}
2391	if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) {
2392		printf( "wrong data in test file. \n" );
2393		goto test_failed_exit;
2394	}
2395
2396	/* we do the above tests twice - once for dup and once for dup2 */
2397	if ( my_loop_counter < 1 ) {
2398		my_loop_counter++;
2399		close( my_newfd );
2400
2401		my_err = dup2( my_fd, my_newfd );
2402		if ( my_err == -1 ) {
2403			printf( "dup2 call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2404			goto test_failed_exit;
2405		}
2406
2407		goto redo;
2408	}
2409
2410	my_err = 0;
2411	goto test_passed_exit;
2412
2413test_failed_exit:
2414	my_err = -1;
2415
2416test_passed_exit:
2417	if ( my_fd != -1 )
2418		close( my_fd );
2419	if ( my_newfd != -1 )
2420		close( my_newfd );
2421	if ( my_pathp != NULL ) {
2422		remove( my_pathp );
2423		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2424	 }
2425	return( my_err );
2426}
2427
2428
2429/*  **************************************************************************************************************
2430 *	Test getrusage system call.
2431 *  **************************************************************************************************************
2432 */
2433int getrusage_test( void * the_argp )
2434{
2435	int				my_err;
2436	struct rusage	my_rusage;
2437
2438	my_err = getrusage( RUSAGE_SELF, &my_rusage );
2439	if ( my_err == -1 ) {
2440		printf( "getrusage failed with error %d - \"%s\" \n", errno, strerror( errno) );
2441		goto test_failed_exit;
2442	}
2443
2444	/* do a sanity check on the getrusage results */
2445	if ( my_rusage.ru_msgrcv > 1000 || my_rusage.ru_msgrcv < 0 ) {
2446		printf( "getrusage seems to report wrong data - ru_msgrcv looks odd. \n" );
2447		goto test_failed_exit;
2448	}
2449	if ( my_rusage.ru_nsignals > 1000 || my_rusage.ru_nsignals < 0 ) {
2450		printf( "getrusage seems to report wrong data - ru_nsignals looks odd. \n" );
2451		goto test_failed_exit;
2452	}
2453
2454	my_err = 0;
2455	goto test_passed_exit;
2456
2457test_failed_exit:
2458	my_err = -1;
2459
2460test_passed_exit:
2461	return( my_err );
2462}
2463
2464/*  **************************************************************************************************************
2465 *	Test getitimer, setitimer, sigaction, sigpending, sigprocmask, sigsuspend, sigwait system calls.
2466 *  **************************************************************************************************************
2467 */
2468
2469int		alarm_global = 0;
2470void test_alarm_handler( int the_arg );
2471void test_alarm_handler( int the_arg )
2472{
2473	alarm_global = 4;
2474	//printf( "test_alarm_handler - got here \n" );
2475	if ( the_arg == 0 ) {
2476	}
2477	return;
2478}
2479
2480void test_signal_handler( int the_arg );
2481void test_signal_handler( int the_arg )
2482{
2483	//printf( "test_signal_handler - got here \n" );
2484	if ( the_arg == 0 ) {
2485	}
2486	return;
2487}
2488
2489int signals_test( void * the_argp )
2490{
2491	int			my_err, my_status;
2492	int			my_fd = -1;
2493	char *		my_pathp = NULL;
2494	pid_t		my_pid, my_wait_pid;
2495	kern_return_t           my_kr;
2496
2497        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2498        if(my_kr != KERN_SUCCESS){
2499                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2500                goto test_failed_exit;
2501        }
2502
2503	*my_pathp = 0x00;
2504	strcat( my_pathp, &g_target_path[0] );
2505	strcat( my_pathp, "/" );
2506
2507	/* create a test file */
2508	my_err = create_random_name( my_pathp, 1 );
2509	if ( my_err != 0 ) {
2510		goto test_failed_exit;
2511	}
2512
2513	/*
2514	 * spin off a child process that we will use for signal related testing.
2515	 */
2516	my_pid = fork( );
2517	if ( my_pid == -1 ) {
2518		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2519		goto test_failed_exit;
2520	}
2521	if ( my_pid == 0 ) {
2522		/*
2523		 * child process - test signal related system calls.
2524		 */
2525		//int					my_counter;
2526		int					my_signal;
2527		sigset_t			my_sigset;
2528		struct sigaction	my_sigaction;
2529#ifdef MAC_OS_X_VERSION_10_5
2530#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
2531		/* If this is Leopard. To allow compiling for Inca x86_64 this definition cannot
2532		 * be included. But it is needed to compile on Leopard.
2533		 */
2534		struct __darwin_sigaltstack	my_sigaltstack;
2535#endif
2536#else
2537		struct sigaltstack	my_sigaltstack;
2538#endif
2539		struct itimerval    my_timer;
2540
2541
2542		/* test getting the current signal stack context */
2543		my_err = sigaltstack( NULL, &my_sigaltstack );
2544		if ( my_err == -1 ) {
2545			printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) );
2546			exit( -1 );
2547		}
2548		if ( (my_sigaltstack.ss_flags & SS_DISABLE) == 0 ) {
2549			printf( "sigaction must have failed - SS_DISABLE is cleared \n" );
2550			exit( -1 );
2551		}
2552
2553		/* set up to catch SIGUSR1 */
2554		my_sigaction.sa_handler = test_signal_handler;
2555		my_sigaction.sa_flags = SA_RESTART;
2556		my_sigaction.sa_mask = 0;
2557
2558		my_err = sigaction( SIGUSR1, &my_sigaction, NULL );
2559		if ( my_err == -1 ) {
2560			printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) );
2561			exit( -1 );
2562		}
2563
2564		/* now suspend until signal SIGUSR1 is sent */
2565		sigemptyset( &my_sigset );
2566		my_err = sigsuspend( &my_sigset );
2567		if ( my_err == -1 ) {
2568			if ( errno != EINTR ) {
2569				printf( "sigsuspend should have returned with errno EINTR \n" );
2570				exit( -1 );
2571			}
2572		}
2573
2574		/* block SIGUSR1 */
2575		sigemptyset( &my_sigset );
2576		sigaddset( &my_sigset, SIGUSR1 );
2577		if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) {
2578			printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2579			exit( -1 );
2580		}
2581		my_err = sigprocmask( SIG_BLOCK, &my_sigset, NULL );
2582		if ( my_err == -1 ) {
2583			printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2584			exit( -1 );
2585		}
2586
2587		/* make sure we are blocking SIGUSR1 */
2588		sigemptyset( &my_sigset );
2589		my_err = sigprocmask( 0, NULL, &my_sigset );
2590		if ( my_err == -1 ) {
2591			printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2592			exit( -1 );
2593		}
2594		if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) {
2595			printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2596			exit( -1 );
2597		}
2598
2599		/* our parent will send a 2nd SIGUSR1 signal which we should now see getting
2600		 * blocked.
2601		 */
2602		sigemptyset( &my_sigset );
2603		sigaddset( &my_sigset, SIGUSR1 );
2604		my_err = sigwait( &my_sigset, &my_signal );
2605		if ( my_err == -1 ) {
2606			printf( "sigwait failed with errno %d - %s \n", errno, strerror( errno ) );
2607			exit( -1 );
2608		}
2609		//printf( "%s - %d - signal 0x%02X %d \n", __FUNCTION__, __LINE__, my_signal, my_signal );
2610		if ( my_signal != SIGUSR1 ) {
2611			printf( "sigwait failed to catch a pending SIGUSR1 signal. \n" );
2612			exit( -1 );
2613		}
2614
2615		/* now unblock SIGUSR1 */
2616		sigfillset( &my_sigset );
2617		sigdelset( &my_sigset, SIGUSR1 );
2618		my_err = sigprocmask( SIG_UNBLOCK, &my_sigset, NULL );
2619		if ( my_err == -1 ) {
2620			printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2621			exit( -1 );
2622		}
2623		if ( sigismember( &my_sigset, SIGUSR1 ) != 0 ) {
2624			printf( "sigprocmask call failed to unblock SIGUSR1 \n" );
2625			exit( -1 );
2626		}
2627
2628		/* test get / setitimer */
2629		timerclear( &my_timer.it_interval );
2630		timerclear( &my_timer.it_value );
2631		my_err = setitimer( ITIMER_VIRTUAL, &my_timer, NULL );
2632		if ( my_err == -1 ) {
2633			printf( "setitimer - ITIMER_VIRTUAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2634			exit( -1 );
2635		}
2636		my_err = setitimer( ITIMER_PROF, &my_timer, NULL );
2637		if ( my_err == -1 ) {
2638			printf( "setitimer - ITIMER_PROF - failed with errno %d - %s \n", errno, strerror( errno ) );
2639			exit( -1 );
2640		}
2641
2642		/* set up to catch SIGALRM */
2643		alarm_global = 0;
2644		my_sigaction.sa_handler = test_alarm_handler;
2645		my_sigaction.sa_flags = SA_RESTART;
2646		my_sigaction.sa_mask = 0;
2647
2648		my_err = sigaction( SIGALRM, &my_sigaction, NULL );
2649		if ( my_err == -1 ) {
2650			printf( "sigaction - SIGALRM - failed with errno %d - %s \n", errno, strerror( errno ) );
2651			exit( -1 );
2652		}
2653
2654		/* set timer for half a second */
2655		my_timer.it_value.tv_usec = (1000000 / 2);
2656		my_err = setitimer( ITIMER_REAL, &my_timer, NULL );
2657		if ( my_err == -1 ) {
2658			printf( "setitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2659			exit( -1 );
2660		}
2661
2662		/* now suspend until signal SIGALRM is sent */
2663		sigfillset( &my_sigset );
2664		sigdelset( &my_sigset, SIGALRM );
2665		my_err = sigsuspend( &my_sigset );
2666		if ( my_err == -1 ) {
2667			if ( errno != EINTR ) {
2668				printf( "sigsuspend should have returned with errno EINTR \n" );
2669				exit( -1 );
2670			}
2671		}
2672		if ( alarm_global != 4 ) {
2673			printf( "setitimer test failed - did not catch SIGALRM \n" );
2674			exit( -1 );
2675		}
2676
2677		/* make sure ITIMER_REAL is now clear */
2678		my_timer.it_value.tv_sec = 44;
2679		my_timer.it_value.tv_usec = 44;
2680		my_err = getitimer( ITIMER_REAL, &my_timer );
2681		if ( my_err == -1 ) {
2682			printf( "getitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2683			exit( -1 );
2684		}
2685		if ( timerisset( &my_timer.it_value ) || timerisset( &my_timer.it_interval ) ) {
2686			printf( "ITIMER_REAL is set, but should not be \n" );
2687			exit( -1 );
2688		}
2689
2690		exit(0);
2691	}
2692
2693	/*
2694	 * parent process - let child set up to suspend then signal it with SIGUSR1
2695	 */
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	/* send 2nd signal to suspended child - which should be blocking SIGUSR1 signals */
2704	sleep( 1 );
2705	my_err = kill( my_pid, SIGUSR1 );
2706	if ( my_err == -1 ) {
2707		printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2708		goto test_failed_exit;
2709	}
2710
2711	/* wait for child to exit */
2712	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2713	if ( my_wait_pid == -1 ) {
2714		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2715		goto test_failed_exit;
2716	}
2717
2718	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2719		goto test_failed_exit;
2720	}
2721
2722	my_err = 0;
2723	goto test_passed_exit;
2724
2725test_failed_exit:
2726	my_err = -1;
2727
2728test_passed_exit:
2729	if ( my_fd != -1 )
2730		close( my_fd );
2731	if ( my_pathp != NULL ) {
2732		remove( my_pathp );
2733		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2734	 }
2735	return( my_err );
2736}
2737
2738/*  **************************************************************************************************************
2739 *	Test getlogin, setlogin system calls.
2740 *  **************************************************************************************************************
2741 */
2742int getlogin_setlogin_test( void * the_argp )
2743{
2744	int			my_err, my_status;
2745	pid_t		my_pid, my_wait_pid;
2746	kern_return_t           my_kr;
2747
2748	if ( g_skip_setuid_tests != 0 ) {
2749		printf("\t skipping this test \n");
2750		my_err = 0;
2751		goto test_passed_exit;
2752	}
2753
2754	/*
2755	 * spin off a child process that we will use for testing.
2756	 */
2757	my_pid = fork( );
2758	if ( my_pid == -1 ) {
2759		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2760		goto test_failed_exit;
2761	}
2762	if ( my_pid == 0 ) {
2763		/*
2764		 * child process - do getlogin and setlogin testing.
2765		 */
2766		char *		my_namep = NULL;
2767		int		my_len;
2768		char *		my_new_namep = NULL;
2769
2770		my_namep = getlogin( );
2771		if ( my_namep == NULL ) {
2772			printf( "getlogin returned NULL name pointer \n" );
2773			my_err = -1;
2774			goto exit_child;
2775		}
2776
2777		my_len = strlen( my_namep ) + 4;
2778
2779	        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_namep, my_len, VM_FLAGS_ANYWHERE);
2780       		 if(my_kr != KERN_SUCCESS){
2781                	printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2782               		my_err = -1;
2783			goto exit_child;
2784        	}
2785
2786		bzero( (void *)my_new_namep, my_len );
2787
2788		strcat( my_new_namep, my_namep );
2789		strcat( my_new_namep, "2" );
2790
2791
2792		/* set new name */
2793		my_err = setlogin( my_new_namep );
2794		if ( my_err == -1 ) {
2795			printf( "When setting new login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) );
2796			my_err = -1;
2797			goto exit_child;
2798		}
2799
2800		/* make sure we set new name */
2801		my_namep = getlogin( );
2802		if ( my_namep == NULL ) {
2803			printf( "getlogin returned NULL name pointer \n" );
2804			my_err = -1;
2805			goto exit_child;
2806		}
2807
2808		if ( memcmp( my_namep, my_new_namep, strlen( my_new_namep ) ) != 0 ) {
2809			printf( "setlogin failed to set the new name \n" );
2810			my_err = -1;
2811			goto exit_child;
2812		}
2813
2814		/* reset to original name */
2815		my_len = strlen ( my_namep );
2816		my_namep[ my_len - 1 ] = '\0';
2817
2818		my_err = setlogin( my_namep );
2819		if ( my_err == -1 ) {
2820			printf( "When resetting login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) );
2821			my_err = -1;
2822			goto exit_child;
2823		}
2824
2825
2826		my_err = 0;
2827exit_child:
2828		if ( my_new_namep != NULL ) {
2829			vm_deallocate(mach_task_self(), (vm_address_t)my_new_namep, my_len);
2830		}
2831		exit( my_err );
2832	}
2833
2834	/* parent process -
2835	 * wait for child to exit
2836	 */
2837	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2838	if ( my_wait_pid == -1 ) {
2839		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2840		goto test_failed_exit;
2841	}
2842
2843	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2844		goto test_failed_exit;
2845	}
2846	my_err = 0;
2847	goto test_passed_exit;
2848
2849test_failed_exit:
2850	my_err = -1;
2851
2852test_passed_exit:
2853	return( my_err );
2854}
2855
2856/*  **************************************************************************************************************
2857 *	Test acct system call.
2858 *  **************************************************************************************************************
2859 */
2860int acct_test( void * the_argp )
2861{
2862	int		my_err, my_status;
2863	int		my_fd = -1;
2864	char *		my_pathp = NULL;
2865	struct acct *	my_acctp;
2866	pid_t		my_pid, my_wait_pid;
2867	ssize_t		my_count;
2868	char		my_buffer[ (sizeof(struct acct) + 32) ];
2869	kern_return_t           my_kr;
2870
2871	if ( g_skip_setuid_tests != 0 ) {
2872		printf("\t skipping this test \n");
2873		my_err = 0;
2874		goto test_passed_exit;
2875	}
2876
2877	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2878        if(my_kr != KERN_SUCCESS){
2879                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2880                goto test_failed_exit;
2881        }
2882
2883	*my_pathp = 0x00;
2884	strcat( my_pathp, &g_target_path[0] );
2885	strcat( my_pathp, "/" );
2886
2887	/* create a test file */
2888	my_err = create_random_name( my_pathp, 1 );
2889	if ( my_err != 0 ) {
2890		goto test_failed_exit;
2891	}
2892
2893	/* enable process accounting */
2894	my_err =  acct( my_pathp );
2895	if ( my_err == -1 ) {
2896		printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2897		goto test_failed_exit;
2898	}
2899
2900	/*
2901	 * spin off a child process that we will use for testing.
2902	 */
2903	my_pid = fork( );
2904	if ( my_pid == -1 ) {
2905		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2906		goto test_failed_exit;
2907	}
2908	if ( my_pid == 0 ) {
2909		char *argv[2];		/* supply valid argv array to execv() */
2910		argv[0] = "/usr/bin/true";
2911		argv[1] = 0;
2912
2913		/*
2914		 * child process - do a little work then exit.
2915		 */
2916		my_err = execv( argv[0], argv);
2917		exit( 0 );
2918	}
2919
2920	/* parent process -
2921	 * wait for child to exit
2922	 */
2923	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2924	if ( my_wait_pid == -1 ) {
2925		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2926		goto test_failed_exit;
2927	}
2928
2929	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2930		printf("unexpected child exit status for accounting test load: %d\n", WEXITSTATUS( my_status));
2931		goto test_failed_exit;
2932	}
2933
2934	/* disable process accounting */
2935	my_err =  acct( NULL );
2936	if ( my_err == -1 ) {
2937		printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2938		goto test_failed_exit;
2939	}
2940
2941	/* now verify that there is accounting info in the log file */
2942	my_fd = open( my_pathp, O_RDONLY, 0 );
2943	if ( my_fd == -1 ) {
2944		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2945		goto test_failed_exit;
2946	}
2947
2948	lseek( my_fd, 0, SEEK_SET );
2949	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
2950	my_count = read( my_fd, &my_buffer[0], sizeof(struct acct) );
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	my_acctp = (struct acct *) &my_buffer[0];
2957
2958	/* first letters in ac_comm should match the name of the executable */
2959	if ( getuid( ) != my_acctp->ac_uid || getgid( ) != my_acctp->ac_gid ||
2960			my_acctp->ac_comm[0] != 't' || my_acctp->ac_comm[1] != 'r' ) {
2961			printf( "------------------------\n" );
2962			printf( "my_acctp->ac_uid = %lu (should be: %lu)\n", (unsigned long) my_acctp->ac_uid, (unsigned long) getuid() );
2963			printf( "my_acctp->ac_gid = %lu (should be: %lu)\n", (unsigned long) my_acctp->ac_gid, (unsigned long) getgid() );
2964
2965			print_acct_debug_strings(my_acctp->ac_comm);
2966
2967		goto test_failed_exit;
2968	}
2969	my_err = 0;
2970	goto test_passed_exit;
2971
2972test_failed_exit:
2973	my_err = -1;
2974
2975test_passed_exit:
2976	if ( my_fd != -1 )
2977		close( my_fd );
2978	if ( my_pathp != NULL ) {
2979		remove( my_pathp );
2980		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2981	 }
2982	return( my_err );
2983}
2984
2985void print_acct_debug_strings( char * my_ac_comm )
2986{
2987	char	my_cmd_str[11]; /* sizeof(acct_cmd) + 1 for '\0' if acct_cmd is bogus */
2988	char	my_hex_str[128];
2989	int 	i;
2990
2991	my_hex_str[0] = '\0';
2992	for(i = 0; i < 10; i++)
2993	{
2994		sprintf( my_hex_str, "%s \'0x%x\' ", my_hex_str, my_ac_comm[i]);
2995	}
2996
2997	memccpy(my_cmd_str, my_ac_comm, '\0', 10);
2998	my_cmd_str[10] = '\0'; /* In case ac_comm was bogus */
2999
3000
3001	printf( "my_acctp->ac_comm = \"%s\" (should begin with: \"tr\")\n", my_cmd_str);
3002	printf( "my_acctp->ac_comm = \"%s\"\n", my_hex_str);
3003	printf( "------------------------\n" );
3004}
3005
3006
3007/*  **************************************************************************************************************
3008 *	Test ioctl system calls.
3009 *  **************************************************************************************************************
3010 */
3011int ioctl_test( void * the_argp )
3012{
3013	int					my_err, my_result;
3014	int					my_fd = -1;
3015	struct statfs *		my_infop;
3016	char *				my_ptr;
3017    int					my_blksize;
3018    long long			my_block_count;
3019	char				my_name[ 128 ];
3020
3021	my_result = getmntinfo( &my_infop, MNT_NOWAIT );
3022	if ( my_result < 1 ) {
3023		printf( "getmntinfo failed with error %d - \"%s\" \n", errno, strerror( errno) );
3024		goto test_failed_exit;
3025	}
3026
3027	/* make this a raw device */
3028	strcpy( &my_name[0], &my_infop->f_mntfromname[0] );
3029	if ( (my_ptr = strrchr( &my_name[0], '/' )) != 0 ) {
3030		if ( my_ptr[1] != 'r' ) {
3031			my_ptr[ strlen( my_ptr ) ] = 0x00;
3032			memmove( &my_ptr[2], &my_ptr[1], (strlen( &my_ptr[1] ) + 1) );
3033			my_ptr[1] = 'r';
3034		}
3035	}
3036
3037	my_fd = open(&my_name[0], O_RDONLY );
3038	if ( my_fd == -1 ) {
3039		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3040		goto test_failed_exit;
3041	}
3042
3043    /* obtain the size of the media (in blocks) */
3044	my_err = ioctl( my_fd, DKIOCGETBLOCKCOUNT, &my_block_count );
3045	if ( my_err == -1 ) {
3046		printf( "ioctl DKIOCGETBLOCKCOUNT failed with error %d - \"%s\" \n", errno, strerror( errno) );
3047		goto test_failed_exit;
3048	}
3049
3050    /* obtain the block size of the media */
3051	my_err = ioctl( my_fd, DKIOCGETBLOCKSIZE, &my_blksize );
3052	if ( my_err == -1 ) {
3053		printf( "ioctl DKIOCGETBLOCKSIZE failed with error %d - \"%s\" \n", errno, strerror( errno) );
3054		goto test_failed_exit;
3055	}
3056	//printf( "my_block_count %qd my_blksize %d \n", my_block_count, my_blksize );
3057
3058	/* make sure the returned data looks somewhat valid */
3059	if ( my_blksize < 0 || my_blksize > (1024 * 1000) ) {
3060		printf( "ioctl appears to have returned incorrect block size data \n" );
3061		goto test_failed_exit;
3062	}
3063
3064	my_err = 0;
3065	goto test_passed_exit;
3066
3067test_failed_exit:
3068	my_err = -1;
3069
3070test_passed_exit:
3071	if ( my_fd != -1 )
3072		close( my_fd );
3073	return( my_err );
3074}
3075
3076/*  **************************************************************************************************************
3077 *	Test mkdir, rmdir, umask system calls.
3078 *  **************************************************************************************************************
3079 */
3080int mkdir_rmdir_umask_test( void * the_argp )
3081{
3082	int				my_err;
3083	int				my_fd = -1;
3084	int				did_umask = 0;
3085	char *			my_pathp = NULL;
3086	mode_t			my_orig_mask;
3087	struct stat		my_sb;
3088	kern_return_t           my_kr;
3089
3090        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3091        if(my_kr != KERN_SUCCESS){
3092                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3093                goto test_failed_exit;
3094        }
3095
3096	*my_pathp = 0x00;
3097	strcat( my_pathp, &g_target_path[0] );
3098	strcat( my_pathp, "/" );
3099
3100	/* get a unique name to use with mkdir */
3101	my_err = create_random_name( my_pathp, 0 );
3102	if ( my_err != 0 ) {
3103		printf( "create_random_name failed with error %d\n", my_err );
3104		goto test_failed_exit;
3105	}
3106
3107	/* set umask to clear WX for other and group and clear X for user */
3108	my_orig_mask = umask( (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) );
3109	did_umask = 1;
3110
3111	/* create a directory with RWX for user, group, other (which should be limited by umask) */
3112	my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3113	if ( my_err == -1 ) {
3114		printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3115		goto test_failed_exit;
3116	}
3117
3118	/* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/
3119	my_err = stat( my_pathp, &my_sb );
3120	if ( my_err != 0 ) {
3121		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3122		goto test_failed_exit;
3123	}
3124	if ( (my_sb.st_mode & (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH)) != 0 ) {
3125		printf( "umask did not limit modes as it should have \n" );
3126		goto test_failed_exit;
3127	}
3128
3129	/* get rid of our test directory */
3130	my_err = rmdir( my_pathp );
3131	if ( my_err == -1 ) {
3132		printf( "rmdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3133		goto test_failed_exit;
3134	}
3135	my_err = 0;
3136	goto test_passed_exit;
3137
3138test_failed_exit:
3139	my_err = -1;
3140
3141test_passed_exit:
3142	if ( my_fd != -1 )
3143		close( my_fd );
3144	if ( my_pathp != NULL ) {
3145		rmdir( my_pathp );
3146		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3147	 }
3148	 if ( did_umask != 0 ) {
3149		umask( my_orig_mask );
3150	 }
3151
3152	return( my_err );
3153}
3154
3155/*  **************************************************************************************************************
3156 *	Test chroot system call.
3157 *  **************************************************************************************************************
3158 */
3159int chroot_test( void * the_argp )
3160{
3161	int			my_err, my_status;
3162	pid_t		my_pid, my_wait_pid;
3163	char *		my_pathp = NULL;
3164	kern_return_t           my_kr;
3165
3166	if ( g_skip_setuid_tests != 0 ) {
3167		printf("\t skipping this test \n");
3168		my_err = 0;
3169		goto test_passed_exit;
3170	}
3171
3172        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3173        if(my_kr != KERN_SUCCESS){
3174                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3175                goto test_failed_exit;
3176        }
3177
3178	*my_pathp = 0x00;
3179	strcat( my_pathp, &g_target_path[0] );
3180	strcat( my_pathp, "/" );
3181
3182	/* get a unique name for our test directory */
3183	my_err = create_random_name( my_pathp, 0 );
3184	if ( my_err != 0 ) {
3185		goto test_failed_exit;
3186	}
3187
3188	/* create a test directory */
3189	my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3190	if ( my_err == -1 ) {
3191		printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3192		goto test_failed_exit;
3193	}
3194
3195	/*
3196	 * spin off a child process that we will use for testing.
3197	 */
3198	my_pid = fork( );
3199	if ( my_pid == -1 ) {
3200		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3201		goto test_failed_exit;
3202	}
3203	if ( my_pid == 0 ) {
3204		/*
3205		 * child process - do getlogin and setlogin testing.
3206		 */
3207		struct stat		my_sb;
3208
3209		/* change our root to our new test directory */
3210		my_err = chroot( my_pathp );
3211		if ( my_err != 0 ) {
3212			printf( "chroot failed with error %d - \"%s\" \n", errno, strerror( errno) );
3213			exit( -1 );
3214		}
3215
3216		/* verify root directory is now an empty directory */
3217		my_err = stat( "/", &my_sb );
3218		if ( my_err != 0 ) {
3219			printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3220			exit( -1 );
3221		}
3222		if ( my_sb.st_nlink > 2 ) {
3223			printf( "root dir should be emnpty! \n" );
3224			exit( -1 );
3225		}
3226		exit( 0 );
3227	}
3228
3229	/* parent process -
3230	 * wait for child to exit
3231	 */
3232	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3233	if ( my_wait_pid == -1 ) {
3234		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3235		goto test_failed_exit;
3236	}
3237
3238	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3239		printf( "bad exit status\n" );
3240		goto test_failed_exit;
3241	}
3242
3243	my_err = 0;
3244	goto test_passed_exit;
3245
3246test_failed_exit:
3247	my_err = -1;
3248
3249test_passed_exit:
3250	if ( my_pathp != NULL ) {
3251		my_err = rmdir( my_pathp );
3252		if ( my_err != 0 ) {
3253			printf( "rmdir failed with error %d - \"%s\" path %p\n", errno, strerror( errno), my_pathp );
3254		}
3255		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3256	}
3257	return( my_err );
3258}
3259
3260/*  **************************************************************************************************************
3261 *	Test getpgrp, getpgid, getsid, setpgid, setpgrp, setsid system calls.
3262 *  **************************************************************************************************************
3263 */
3264int process_group_test( void * the_argp )
3265{
3266	int		my_err = 0, i = 0;
3267	pid_t		my_session_id, my_pid, my_process_group;
3268
3269	/* get current session ID, pgid, and pid */
3270	my_session_id = getsid( 0 );
3271	if ( my_session_id == -1 ) {
3272		printf( "getsid call failed with error %d - \"%s\" \n",
3273				errno, strerror( errno ) );
3274		goto test_failed_exit;
3275	}
3276
3277	my_pid = getpid( );
3278	my_process_group = getpgrp( );
3279
3280	/* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */
3281	if ( my_process_group != getpgid( 0 ) ) {
3282		printf( "getpgrp and getpgid did not return the same process group ID \n" );
3283		printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group );
3284		goto test_failed_exit;
3285	}
3286
3287	if ( my_pid == my_process_group ) {
3288		/* we are process group leader */
3289		my_err = setsid( );
3290		if ( my_err == 0  || errno != EPERM ) {
3291			printf( "setsid call should have failed with EPERM\n" );
3292			goto test_failed_exit;
3293		}
3294	} else {
3295		/* we are not process group leader: try creating new session */
3296		my_err = setsid( );
3297		if ( my_err == -1 ) {
3298			printf( "setsid call failed with error %d - \"%s\" \n",
3299					errno, strerror( errno ) );
3300			goto test_failed_exit;
3301		}
3302
3303		if ( my_process_group == getpgid( 0 ) ) {
3304			printf( "process group was not reset \n" );
3305			goto test_failed_exit;
3306		}
3307	}
3308
3309	/* find an unused process group ID */
3310	for ( i = 10000; i < 1000000; i++ ) {
3311		my_process_group = getpgid( i );
3312		if ( my_process_group == -1 ) {
3313			break;
3314		}
3315	}
3316
3317	/* this should fail */
3318	my_err = setpgid( 0, my_process_group );
3319	if ( my_err != -1 ) {
3320		printf( "setpgid should have failed, but did not \n" );
3321		goto test_failed_exit;
3322	}
3323
3324	my_err = 0;
3325	goto test_passed_exit;
3326
3327test_failed_exit:
3328	my_err = -1;
3329
3330test_passed_exit:
3331	return( my_err );
3332}
3333
3334/*  **************************************************************************************************************
3335 *	Test fcntl system calls.
3336 *  **************************************************************************************************************
3337 */
3338int fcntl_test( void * the_argp )
3339{
3340	int			my_err, my_result, my_tmep;
3341	int			my_fd = -1;
3342	int			my_newfd = -1;
3343	char *		my_pathp = NULL;
3344	kern_return_t           my_kr;
3345
3346        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3347        if(my_kr != KERN_SUCCESS){
3348                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3349                goto test_failed_exit;
3350        }
3351
3352	*my_pathp = 0x00;
3353	strcat( my_pathp, &g_target_path[0] );
3354	strcat( my_pathp, "/" );
3355
3356	/* create a test file */
3357	my_err = create_random_name( my_pathp, 1 );
3358	if ( my_err != 0 ) {
3359		goto test_failed_exit;
3360	}
3361
3362	/* open our test file and use fcntl to get / set file descriptor flags */
3363	my_fd = open( my_pathp, O_RDONLY, 0 );
3364	if ( my_fd == -1 ) {
3365		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3366		goto test_failed_exit;
3367	}
3368
3369	my_result = fcntl( my_fd, F_GETFD, 0 );
3370	if ( my_result == -1 ) {
3371		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3372		goto test_failed_exit;
3373	}
3374
3375	my_tmep = (my_result & FD_CLOEXEC);
3376	if ( my_tmep ) {
3377		/* FD_CLOEXEC is on, let's turn it off */
3378		my_result = fcntl( my_fd, F_SETFD, 0 );
3379	}
3380	else {
3381		/* FD_CLOEXEC is off, let's turn it on */
3382		my_result = fcntl( my_fd, F_SETFD, 1 );
3383	}
3384	if ( my_result == -1 ) {
3385		printf( "fcntl - F_SETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3386		goto test_failed_exit;
3387	}
3388
3389	/* now check to see if it is set correctly */
3390	my_result = fcntl( my_fd, F_GETFD, 0 );
3391	if ( my_result == -1 ) {
3392		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3393		goto test_failed_exit;
3394	}
3395	if ( my_tmep == (my_result & 0x01) ) {
3396		printf( "fcntl - F_SETFD failed to set FD_CLOEXEC correctly!!! \n" );
3397		goto test_failed_exit;
3398	}
3399
3400	/* dup it to a new fd with FD_CLOEXEC forced on */
3401
3402	my_result = fcntl( my_fd, F_DUPFD_CLOEXEC, 0);
3403	if ( my_result == -1 ) {
3404		printf( "fcntl - F_DUPFD_CLOEXEC - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3405		goto test_failed_exit;
3406	}
3407	my_newfd = my_result;
3408
3409	/* check to see that it too is marked with FD_CLOEXEC */
3410
3411	my_result = fcntl( my_newfd, F_GETFD, 0);
3412	if ( my_result == -1 ) {
3413		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3414		goto test_failed_exit;
3415	}
3416	if ( (my_result & FD_CLOEXEC) == 0 ) {
3417		printf( "fcntl - F_DUPFD_CLOEXEC failed to set FD_CLOEXEC!!! \n" );
3418		goto test_failed_exit;
3419	}
3420
3421	close( my_newfd );
3422	my_newfd = -1;
3423
3424#if !TARGET_OS_EMBEDDED /* This section of the test is specific for the desktop platform, refer <rdar://problem/8850905>*/
3425	/* While we're here, dup it via an open of /dev/fd/<fd> .. */
3426
3427	{
3428		char devfdpath[PATH_MAX];
3429
3430		(void) snprintf( devfdpath, sizeof (devfdpath),
3431			"/dev/fd/%u", my_fd );
3432		my_result = open( devfdpath, O_RDONLY | O_CLOEXEC );
3433	}
3434	if ( my_result == -1 ) {
3435		printf( "open call failed on /dev/fd/%u with error %d - \"%s\" \n", my_fd, errno, strerror( errno) );
3436		goto test_failed_exit;
3437	}
3438	my_newfd = my_result;
3439
3440	/* check to see that it too is marked with FD_CLOEXEC */
3441
3442	my_result = fcntl( my_newfd, F_GETFD, 0);
3443	if ( my_result == -1 ) {
3444		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3445		goto test_failed_exit;
3446	}
3447	if ( (my_result & FD_CLOEXEC) == 0 ) {
3448		printf( "fcntl - O_CLOEXEC open of /dev/fd/%u failed to set FD_CLOEXEC!!! \n", my_fd );
3449		goto test_failed_exit;
3450	}
3451	close ( my_newfd );
3452	my_newfd = -1;
3453#endif
3454	my_err = 0;
3455	goto test_passed_exit;
3456
3457test_failed_exit:
3458	my_err = -1;
3459
3460test_passed_exit:
3461	if ( my_newfd != -1)
3462		close ( my_newfd );
3463	if ( my_fd != -1 )
3464		close( my_fd );
3465	if ( my_pathp != NULL ) {
3466		remove( my_pathp );
3467		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3468	 }
3469	return( my_err );
3470}
3471
3472/*  **************************************************************************************************************
3473 *	Test getpriority, setpriority system calls.
3474 *  **************************************************************************************************************
3475 */
3476int getpriority_setpriority_test( void * the_argp )
3477{
3478	int			my_err;
3479	int			my_priority;
3480	int			my_new_priority;
3481
3482	/* getpriority returns scheduling priority so -1 is a valid value */
3483	errno = 0;
3484	my_priority = getpriority( PRIO_PROCESS, 0 );
3485	if ( my_priority == -1 && errno != 0 ) {
3486		printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3487		goto test_failed_exit;
3488	}
3489
3490	/* change scheduling priority */
3491	my_new_priority = (my_priority == PRIO_MIN) ? (my_priority + 10) : (PRIO_MIN);
3492	my_err = setpriority( PRIO_PROCESS, 0, my_new_priority );
3493	if ( my_err == -1 ) {
3494		printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3495		goto test_failed_exit;
3496	}
3497
3498	/* verify change */
3499	errno = 0;
3500	my_priority = getpriority( PRIO_PROCESS, 0 );
3501	if ( my_priority == -1 && errno != 0 ) {
3502		printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3503		goto test_failed_exit;
3504	}
3505
3506	if ( my_priority != my_new_priority ) {
3507		printf( "setpriority - failed to set correct scheduling priority \n" );
3508		goto test_failed_exit;
3509	}
3510
3511	/* reset scheduling priority */
3512	my_err = setpriority( PRIO_PROCESS, 0, 0 );
3513	if ( my_err == -1 ) {
3514		printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3515		goto test_failed_exit;
3516	}
3517
3518	my_err = 0;
3519	goto test_passed_exit;
3520
3521test_failed_exit:
3522	my_err = -1;
3523
3524test_passed_exit:
3525	return( my_err );
3526}
3527
3528/*  **************************************************************************************************************
3529 *	Test futimes, gettimeofday, settimeofday, utimes system calls.
3530 *  **************************************************************************************************************
3531 */
3532int time_tests( void * the_argp )
3533{
3534	int					my_err;
3535	int					my_fd = -1;
3536	char *				my_pathp = NULL;
3537	struct timeval		my_orig_time;
3538	struct timeval		my_temp_time;
3539	struct timeval		my_utimes[4];
3540	struct timezone		my_tz;
3541	struct stat			my_sb;
3542	kern_return_t           my_kr;
3543
3544	if ( g_skip_setuid_tests != 0 ) {
3545		printf( "\t skipping this test \n" );
3546		my_err = 0;
3547		goto test_passed_exit;
3548	}
3549
3550        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3551        if(my_kr != KERN_SUCCESS){
3552                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3553                goto test_failed_exit;
3554        }
3555
3556	*my_pathp = 0x00;
3557	strcat( my_pathp, &g_target_path[0] );
3558	strcat( my_pathp, "/" );
3559
3560	/* create a test file */
3561	my_err = create_random_name( my_pathp, 1 );
3562	if ( my_err != 0 ) {
3563		goto test_failed_exit;
3564	}
3565
3566	my_err = gettimeofday( &my_orig_time, &my_tz );
3567	if ( my_err == -1 ) {
3568		printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3569		goto test_failed_exit;
3570	}
3571	//printf( "tv_sec %d tv_usec %ld \n", my_orig_time.tv_sec, my_orig_time.tv_usec );
3572
3573	my_temp_time = my_orig_time;
3574	my_temp_time.tv_sec -= 60;
3575	my_err = settimeofday( &my_temp_time, NULL );
3576	if ( my_err == -1 ) {
3577		printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3578		goto test_failed_exit;
3579	}
3580
3581	my_err = gettimeofday( &my_temp_time, NULL );
3582	if ( my_err == -1 ) {
3583		printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3584		goto test_failed_exit;
3585	}
3586	//printf( "tv_sec %d tv_usec %ld \n", my_temp_time.tv_sec, my_temp_time.tv_usec );
3587	if ( my_orig_time.tv_sec <= my_temp_time.tv_sec ) {
3588		printf( "settimeofday did not set correct time \n" );
3589		goto test_failed_exit;
3590	}
3591
3592	/* set time back to original value plus 1 second */
3593	my_temp_time = my_orig_time;
3594	my_temp_time.tv_sec += 1;
3595	my_err = settimeofday( &my_temp_time, NULL );
3596	if ( my_err == -1 ) {
3597		printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3598		goto test_failed_exit;
3599	}
3600
3601	/* test utimes and futimes - get current access and mod times then change them */
3602	my_err = stat( my_pathp, &my_sb );
3603	if ( my_err != 0 ) {
3604		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3605		goto test_failed_exit;
3606	}
3607	TIMESPEC_TO_TIMEVAL( &my_utimes[0], &my_sb.st_atimespec );
3608	TIMESPEC_TO_TIMEVAL( &my_utimes[1], &my_sb.st_mtimespec );
3609	my_utimes[0].tv_sec -= 120;		/* make access time 2 minutes older */
3610	my_utimes[1].tv_sec -= 120;		/* make mod time 2 minutes older */
3611
3612	my_err = utimes( my_pathp, &my_utimes[0] );
3613	if ( my_err == -1 ) {
3614		printf( "utimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3615		goto test_failed_exit;
3616	}
3617
3618	/* make sure the correct times are set */
3619	my_err = stat( my_pathp, &my_sb );
3620	if ( my_err != 0 ) {
3621		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3622		goto test_failed_exit;
3623	}
3624	TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3625	TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3626	if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3627		 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3628		printf( "utimes failed to set access and mod times \n" );
3629		goto test_failed_exit;
3630	}
3631
3632	my_fd = open( my_pathp, O_RDWR, 0 );
3633	if ( my_fd == -1 ) {
3634		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3635		goto test_failed_exit;
3636	}
3637
3638	my_utimes[0].tv_sec -= 120;  /* make access time 2 minutes older */
3639	my_utimes[1].tv_sec -= 120;  /* make mod time 2 minutes older */
3640	my_err = futimes( my_fd, &my_utimes[0] );
3641	if ( my_err == -1 ) {
3642		printf( "futimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3643		goto test_failed_exit;
3644	}
3645
3646	/* make sure the correct times are set */
3647	my_err = stat( my_pathp, &my_sb );
3648	if ( my_err != 0 ) {
3649		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3650		goto test_failed_exit;
3651	}
3652	TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3653	TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3654	if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3655		 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3656		printf( "futimes failed to set access and mod times \n" );
3657		goto test_failed_exit;
3658	}
3659
3660	my_err = 0;
3661	goto test_passed_exit;
3662
3663test_failed_exit:
3664	my_err = -1;
3665
3666test_passed_exit:
3667	if ( my_fd != -1 )
3668		close( my_fd );
3669	if ( my_pathp != NULL ) {
3670		remove( my_pathp );
3671		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3672	 }
3673	return( my_err );
3674}
3675
3676/*  **************************************************************************************************************
3677 *	Test rename, stat system calls.
3678 *  **************************************************************************************************************
3679 */
3680int rename_test( void * the_argp )
3681{
3682	int				my_err;
3683	char *			my_pathp = NULL;
3684	char *			my_new_pathp = NULL;
3685	ino_t			my_file_id;
3686	struct stat		my_sb;
3687	kern_return_t           my_kr;
3688
3689        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3690        if(my_kr != KERN_SUCCESS){
3691                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3692                goto test_failed_exit;
3693        }
3694
3695	*my_pathp = 0x00;
3696	strcat( my_pathp, &g_target_path[0] );
3697	strcat( my_pathp, "/" );
3698
3699	/* create a test file */
3700	my_err = create_random_name( my_pathp, 1 );
3701	if ( my_err != 0 ) {
3702		goto test_failed_exit;
3703	}
3704
3705        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3706        if(my_kr != KERN_SUCCESS){
3707                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3708                goto test_failed_exit;
3709        }
3710
3711	*my_new_pathp = 0x00;
3712	strcat( my_new_pathp, &g_target_path[0] );
3713	strcat( my_new_pathp, "/" );
3714
3715	/* get a unique name for our rename test */
3716	my_err = create_random_name( my_new_pathp, 0 );
3717	if ( my_err != 0 ) {
3718		goto test_failed_exit;
3719	}
3720
3721	/* save file ID for later use */
3722	my_err = stat( my_pathp, &my_sb );
3723	if ( my_err != 0 ) {
3724		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3725		goto test_failed_exit;
3726	}
3727	my_file_id = my_sb.st_ino;
3728
3729	/* test rename */
3730	my_err = rename( my_pathp, my_new_pathp );
3731	if ( my_err == -1 ) {
3732		printf( "rename - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3733		goto test_failed_exit;
3734	}
3735
3736	/* make sure old name is no longer there */
3737	my_err = stat( my_pathp, &my_sb );
3738	if ( my_err == 0 ) {
3739		printf( "rename call failed - found old name \n" );
3740		goto test_failed_exit;
3741	}
3742
3743	/* make sure new name is there and is correct file id */
3744	my_err = stat( my_new_pathp, &my_sb );
3745	if ( my_err != 0 ) {
3746		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3747		goto test_failed_exit;
3748	}
3749	if ( my_file_id != my_sb.st_ino ) {
3750		printf( "rename failed - wrong file id \n" );
3751		goto test_failed_exit;
3752	}
3753
3754	my_err = 0;
3755	goto test_passed_exit;
3756
3757test_failed_exit:
3758	my_err = -1;
3759
3760test_passed_exit:
3761	if ( my_pathp != NULL ) {
3762		remove( my_pathp );
3763		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3764	 }
3765	if ( my_new_pathp != NULL ) {
3766		remove( my_new_pathp );
3767		vm_deallocate(mach_task_self(), (vm_address_t)my_new_pathp, PATH_MAX);
3768	 }
3769	return( my_err );
3770}
3771
3772/*  **************************************************************************************************************
3773 *	Test locking system calls.
3774 *  **************************************************************************************************************
3775 */
3776int locking_test( void * the_argp )
3777{
3778	int			my_err, my_status;
3779	pid_t		my_pid, my_wait_pid;
3780	int			my_fd = -1;
3781	char *		my_pathp = NULL;
3782	kern_return_t           my_kr;
3783
3784        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3785        if(my_kr != KERN_SUCCESS){
3786                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3787                goto test_failed_exit;
3788        }
3789
3790	*my_pathp = 0x00;
3791	strcat( my_pathp, &g_target_path[0] );
3792	strcat( my_pathp, "/" );
3793
3794	/* create a test file */
3795	my_err = create_random_name( my_pathp, 1 );
3796	if ( my_err != 0 ) {
3797		goto test_failed_exit;
3798	}
3799
3800	/* test flock */
3801	my_fd = open( my_pathp, O_RDWR, 0 );
3802	if ( my_fd == -1 ) {
3803		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3804		goto test_failed_exit;
3805	}
3806
3807	my_err =  flock( my_fd, LOCK_EX );
3808	if ( my_err == -1 ) {
3809		printf( "flock - LOCK_EX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3810		goto test_failed_exit;
3811	}
3812
3813	/*
3814	 * spin off a child process that we will use for testing.
3815	 */
3816	my_pid = fork( );
3817	if ( my_pid == -1 ) {
3818		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3819		goto test_failed_exit;
3820	}
3821	if ( my_pid == 0 ) {
3822		/*
3823		 * child process.
3824		 */
3825		int			my_child_fd = -1;
3826		int			my_child_err;
3827
3828		my_child_fd = open( my_pathp, O_RDWR, 0 );
3829		if ( my_child_fd == -1 ) {
3830			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3831			my_child_err = -1;
3832			goto child_exit;
3833		}
3834
3835		my_err =  flock( my_child_fd, (LOCK_EX | LOCK_NB) );
3836		if ( my_err == -1 ) {
3837			if ( errno != EWOULDBLOCK ) {
3838				printf( "flock call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3839				my_child_err = -1;
3840				goto child_exit;
3841			}
3842		}
3843		else {
3844			printf( "flock call should have failed with EWOULDBLOCK err \n" );
3845			my_child_err = -1;
3846			goto child_exit;
3847		}
3848		my_child_err = 0;
3849child_exit:
3850		if ( my_child_fd != -1 )
3851			close( my_child_fd );
3852		exit( my_child_err );
3853	}
3854
3855	/* parent process -
3856	 * wait for child to exit
3857	 */
3858	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3859	if ( my_wait_pid == -1 ) {
3860		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3861		goto test_failed_exit;
3862	}
3863
3864	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3865		goto test_failed_exit;
3866	}
3867
3868	my_err =  flock( my_fd, LOCK_UN );
3869	if ( my_err == -1 ) {
3870		printf( "flock - LOCK_UN - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3871		goto test_failed_exit;
3872	}
3873
3874	my_err = 0;
3875	goto test_passed_exit;
3876
3877test_failed_exit:
3878	my_err = -1;
3879
3880test_passed_exit:
3881	if ( my_fd != -1 )
3882		close( my_fd );
3883	if ( my_pathp != NULL ) {
3884		remove( my_pathp );
3885		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3886	 }
3887	return( my_err );
3888}
3889
3890/*  **************************************************************************************************************
3891 *	Test mkfifo system calls.
3892 *  **************************************************************************************************************
3893 */
3894int mkfifo_test( void * the_argp )
3895{
3896	int			my_err, my_status;
3897	pid_t		my_pid, my_wait_pid;
3898	int			my_fd = -1;
3899	char *		my_pathp = NULL;
3900	ssize_t		my_result;
3901	off_t		my_current_offset;
3902	kern_return_t           my_kr;
3903
3904        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3905        if(my_kr != KERN_SUCCESS){
3906                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3907                goto test_failed_exit;
3908        }
3909
3910	*my_pathp = 0x00;
3911	strcat( my_pathp, &g_target_path[0] );
3912	strcat( my_pathp, "/" );
3913
3914	/* get unique name for our fifo */
3915	my_err = create_random_name( my_pathp, 0 );
3916	if ( my_err != 0 ) {
3917		goto test_failed_exit;
3918	}
3919
3920	my_err = mkfifo( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
3921	if ( my_err != 0 ) {
3922		printf( "mkfifo failed with errno %d - %s. \n", errno, strerror( errno ) );
3923		goto test_failed_exit;
3924	}
3925
3926	/*
3927	 * spin off a child process that we will use for testing.
3928	 */
3929	my_pid = fork( );
3930	if ( my_pid == -1 ) {
3931		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3932		goto test_failed_exit;
3933	}
3934	if ( my_pid == 0 ) {
3935		/*
3936		 * child process.
3937		 */
3938		int			my_child_fd = -1;
3939		int			my_child_err;
3940		char		my_buffer[64];
3941
3942		/* open read end of fifo */
3943		my_child_fd = open( my_pathp, O_RDWR, 0 );
3944		if ( my_child_fd == -1 ) {
3945			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3946			my_child_err = -1;
3947			goto child_exit;
3948		}
3949
3950		/* read message from parent */
3951		bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
3952		my_result = read( my_child_fd, &my_buffer[0], sizeof(my_buffer) );
3953		if ( my_result == -1 ) {
3954			printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3955			my_child_err = -1;
3956			goto child_exit;
3957		}
3958		if ( strcmp( "parent to child", &my_buffer[0] ) != 0 ) {
3959			printf( "read wrong message from parent \n" );
3960			my_child_err = -1;
3961			goto child_exit;
3962		}
3963
3964		my_child_err = 0;
3965child_exit:
3966		if ( my_child_fd != -1 )
3967			close( my_child_fd );
3968		exit( my_child_err );
3969	}
3970
3971	/* parent process - open write end of fifo
3972	 */
3973	my_fd = open( my_pathp, O_WRONLY, 0 );
3974	if ( my_fd == -1 ) {
3975		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3976		goto test_failed_exit;
3977	}
3978
3979	/* make sure we can't seek on a fifo */
3980	my_current_offset = lseek( my_fd, 0, SEEK_CUR );
3981	if ( my_current_offset != -1 ) {
3982		printf( "lseek on fifo should fail but did not \n" );
3983		goto test_failed_exit;
3984	}
3985
3986	my_result = write( my_fd, "parent to child", 15 );
3987	if ( my_result == -1 ) {
3988		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3989		goto test_failed_exit;
3990	}
3991
3992	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3993	if ( my_wait_pid == -1 ) {
3994		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3995		goto test_failed_exit;
3996	}
3997
3998	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3999		goto test_failed_exit;
4000	}
4001
4002	my_err = 0;
4003	goto test_passed_exit;
4004
4005test_failed_exit:
4006	my_err = -1;
4007
4008test_passed_exit:
4009	if ( my_fd != -1 )
4010		close( my_fd );
4011	if ( my_pathp != NULL ) {
4012		remove( my_pathp );
4013		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4014	 }
4015	return( my_err );
4016}
4017
4018/*  **************************************************************************************************************
4019 *	Test quotactl system calls.
4020 *  **************************************************************************************************************
4021 */
4022int quotactl_test( void * the_argp )
4023{
4024#if !TARGET_OS_EMBEDDED
4025	int				my_err;
4026	int				is_quotas_on = 0;
4027	struct dqblk	my_quota_blk;
4028
4029	if ( g_skip_setuid_tests != 0 ) {
4030		printf( "\t skipping this test \n" );
4031		my_err = 0;
4032		goto test_passed_exit;
4033	}
4034
4035	/* start off by checking the status of quotas on the boot volume */
4036	my_err = quotactl( "/mach_kernel", QCMD(Q_QUOTASTAT, USRQUOTA), 0, (caddr_t)&is_quotas_on );
4037	if ( my_err == -1 ) {
4038		printf( "quotactl - Q_QUOTASTAT - failed with errno %d - %s \n", errno, strerror( errno ) );
4039		goto test_failed_exit;
4040	}
4041
4042	if ( is_quotas_on == 0 ) {
4043		/* quotas are off */
4044		my_err = 0;
4045		goto test_passed_exit;
4046	}
4047
4048	my_err = quotactl( "/mach_kernel", QCMD(Q_GETQUOTA, USRQUOTA), getuid(), (caddr_t)&my_quota_blk );
4049	if ( my_err == -1 ) {
4050		printf( "quotactl - Q_GETQUOTA - failed with errno %d - %s \n", errno, strerror( errno ) );
4051		goto test_failed_exit;
4052	}
4053
4054	my_err = 0;
4055	goto test_passed_exit;
4056
4057test_failed_exit:
4058	my_err = -1;
4059
4060test_passed_exit:
4061	return( my_err );
4062#else
4063	printf( "\t--> Not supported on EMBEDDED TARGET\n" );
4064	return 0;
4065#endif
4066}
4067
4068/*  **************************************************************************************************************
4069 *	Test getrlimit, setrlimit system calls.
4070 *  **************************************************************************************************************
4071 */
4072int limit_tests( void * the_argp )
4073{
4074	int				my_err;
4075	struct rlimit	my_current_rlimit;
4076	struct rlimit	my_rlimit;
4077
4078 	my_err = getrlimit( RLIMIT_NOFILE, &my_current_rlimit );
4079	if ( my_err == -1 ) {
4080		printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4081		goto test_failed_exit;
4082	}
4083	if ( my_current_rlimit.rlim_cur != RLIM_INFINITY ) {
4084		if ( my_current_rlimit.rlim_cur != my_current_rlimit.rlim_max )
4085			my_current_rlimit.rlim_cur += 1;
4086		else
4087			my_current_rlimit.rlim_cur -= 1;
4088		my_rlimit.rlim_cur = my_current_rlimit.rlim_cur;
4089		my_rlimit.rlim_max = my_current_rlimit.rlim_max;
4090		my_err = setrlimit( RLIMIT_NOFILE, &my_rlimit );
4091		if ( my_err == -1 ) {
4092			printf( "setrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4093			goto test_failed_exit;
4094		}
4095
4096		/* verify that we set a new limit */
4097		bzero( (void *) &my_rlimit, sizeof( my_rlimit ) );
4098		my_err = getrlimit( RLIMIT_NOFILE, &my_rlimit );
4099		if ( my_err == -1 ) {
4100			printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4101			goto test_failed_exit;
4102		}
4103		if ( my_rlimit.rlim_cur != my_current_rlimit.rlim_cur ) {
4104			printf( "failed to get/set new RLIMIT_NOFILE soft limit \n" );
4105			printf( "soft limits - current %lld should be %lld \n", my_rlimit.rlim_cur, my_current_rlimit.rlim_cur );
4106			goto test_failed_exit;
4107		}
4108
4109#if CONFORMANCE_CHANGES_IN_XNU // can't do this check until conformance changes get into xnu
4110		printf( "hard limits - current %lld should be %lld \n", my_rlimit.rlim_max, my_current_rlimit.rlim_max );
4111		if ( my_rlimit.rlim_max != my_current_rlimit.rlim_max ) {
4112			printf( "failed to get/set new RLIMIT_NOFILE hard limit \n" );
4113			goto test_failed_exit;
4114		}
4115#endif
4116
4117		/*
4118		 * A test for a limit that won't fit in a signed 32 bits, a la 5414697
4119		 * Note: my_rlimit should still have a valid rlim_max.
4120		 */
4121		long long biglim = 2147483649ll;	/* Just over 2^31 */
4122		my_rlimit.rlim_cur = biglim;
4123		my_err = setrlimit(RLIMIT_CPU, &my_rlimit);
4124		if (my_err == -1) {
4125			printf("failed to set large limit.\n");
4126			goto test_failed_exit;
4127		}
4128
4129		bzero(&my_rlimit, sizeof(struct rlimit));
4130		my_err = getrlimit(RLIMIT_CPU, &my_rlimit);
4131		if (my_err == -1) {
4132			printf("after setting large value, failed to getrlimit().\n");
4133			goto test_failed_exit;
4134		}
4135
4136		if (my_rlimit.rlim_cur != biglim) {
4137			printf("didn't retrieve large limit.\n");
4138			goto test_failed_exit;
4139		}
4140	}
4141
4142	my_err = 0;
4143	goto test_passed_exit;
4144
4145test_failed_exit:
4146	my_err = -1;
4147
4148test_passed_exit:
4149	return( my_err );
4150}
4151
4152/*  **************************************************************************************************************
4153 *	Test getattrlist, getdirentriesattr, setattrlist system calls.
4154 *  **************************************************************************************************************
4155 */
4156struct test_attr_buf {
4157	uint32_t			length;
4158	fsobj_type_t		obj_type;
4159	fsobj_id_t			obj_id;
4160	struct timespec   	backup_time;
4161};
4162
4163typedef struct test_attr_buf test_attr_buf;
4164
4165int directory_tests( void * the_argp )
4166{
4167	int					my_err, done, found_it, i;
4168	int					my_fd = -1;
4169	int					is_ufs = 0;
4170	char *				my_pathp = NULL;
4171	char *				my_bufp = NULL;
4172	char *				my_file_namep;
4173#ifdef __LP64__
4174	unsigned int		my_base;
4175	unsigned int		my_count;
4176	unsigned int		my_new_state;
4177#else
4178	unsigned long		my_base;
4179	unsigned long		my_count;
4180	unsigned long		my_new_state;
4181#endif
4182	fsobj_id_t			my_obj_id;
4183	struct timespec		my_new_backup_time;
4184	struct attrlist		my_attrlist;
4185	test_attr_buf		my_attr_buf[4];
4186	struct statfs 		my_statfs_buf;
4187	kern_return_t           my_kr;
4188
4189	/* need to know type of file system */
4190	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4191	if ( my_err == -1 ) {
4192		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4193		goto test_failed_exit;
4194	}
4195	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4196		is_ufs = 1;
4197	}
4198
4199        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE);
4200        if(my_kr != KERN_SUCCESS){
4201                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4202                goto test_failed_exit;
4203        }
4204
4205        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4206        if(my_kr != KERN_SUCCESS){
4207                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4208                goto test_failed_exit;
4209        }
4210
4211	*my_pathp = 0x00;
4212	strcat( my_pathp, &g_target_path[0] );
4213	strcat( my_pathp, "/" );
4214
4215	/* create a test file */
4216	my_err = create_random_name( my_pathp, 1 );
4217	if ( my_err != 0 ) {
4218		goto test_failed_exit;
4219	}
4220
4221	/* get pointer to just the file name */
4222	my_file_namep = strrchr( my_pathp, '/' );
4223	my_file_namep++;
4224
4225	/* check out the  test directory */
4226	my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4227	if ( my_fd == -1 ) {
4228		printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4229		goto test_failed_exit;
4230	}
4231
4232	/* test get/setattrlist */
4233	memset( &my_attrlist, 0, sizeof(my_attrlist) );
4234	my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4235	my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4236	my_err = getattrlist( my_pathp, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf[0]), 0 );
4237
4238	if ( my_err != 0 ) {
4239		if ( errno == ENOTSUP && is_ufs ) {
4240			/* getattr calls not supported on ufs */
4241			my_err = 0;
4242			goto test_passed_exit;
4243		}
4244		printf( "getattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4245		goto test_failed_exit;
4246	}
4247	/* validate returned data */
4248	if ( my_attr_buf[0].obj_type != VREG ) {
4249		printf( "getattrlist returned incorrect obj_type data. \n" );
4250		goto test_failed_exit;
4251	}
4252
4253	/* set new backup time */
4254	my_obj_id = my_attr_buf[0].obj_id;
4255	my_new_backup_time = my_attr_buf[0].backup_time;
4256	my_new_backup_time.tv_sec += 60;
4257	my_attr_buf[0].backup_time.tv_sec = my_new_backup_time.tv_sec;
4258	my_attrlist.commonattr = (ATTR_CMN_BKUPTIME);
4259	my_err = setattrlist( my_pathp, &my_attrlist, &my_attr_buf[0].backup_time, sizeof(my_attr_buf[0].backup_time), 0 );
4260	if ( my_err != 0 ) {
4261		printf( "setattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4262		goto test_failed_exit;
4263	}
4264
4265	/* validate setattrlist using getdirentriesattr */
4266	close( my_fd );
4267	my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4268	if ( my_fd == -1 ) {
4269		printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4270		goto test_failed_exit;
4271	}
4272	memset( &my_attrlist, 0, sizeof(my_attrlist) );
4273	memset( &my_attr_buf, 0, sizeof(my_attr_buf) );
4274	my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4275	my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4276	my_count = 4;
4277	my_base = 0;
4278	my_err = getdirentriesattr( my_fd, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf), &my_count,
4279								&my_base, &my_new_state, 0 );
4280	if ( my_err < 0 ) {
4281		printf( "getdirentriesattr call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4282		goto test_failed_exit;
4283	}
4284
4285	found_it = 0;
4286	for ( i = 0; i < my_count; i++ ) {
4287		if ( my_attr_buf[i].obj_id.fid_objno == my_obj_id.fid_objno &&
4288			 my_attr_buf[i].obj_id.fid_generation == my_obj_id.fid_generation ) {
4289			found_it = 1;
4290			if ( my_attr_buf[i].backup_time.tv_sec !=  my_new_backup_time.tv_sec ) {
4291				printf( "setattrlist failed to set backup time. \n" );
4292				goto test_failed_exit;
4293			}
4294		}
4295	}
4296	if ( found_it == 0 ) {
4297		printf( "getdirentriesattr failed to find test file. \n" );
4298		goto test_failed_exit;
4299	}
4300
4301	my_err = 0;
4302	goto test_passed_exit;
4303
4304test_failed_exit:
4305	if(my_err != 0)
4306		my_err = -1;
4307
4308test_passed_exit:
4309	if ( my_fd != -1 )
4310		close( my_fd );
4311	if ( my_pathp != NULL ) {
4312		remove( my_pathp );
4313		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4314	 }
4315	if ( my_bufp != NULL ) {
4316		vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5));
4317	 }
4318	return( my_err );
4319}
4320
4321/*  **************************************************************************************************************
4322 *	Test exchangedata system calls.
4323 *  **************************************************************************************************************
4324 */
4325int exchangedata_test( void * the_argp )
4326{
4327	int				my_err;
4328	int				my_fd1 = -1;
4329	int				my_fd2 = -1;
4330	char *			my_file1_pathp = NULL;
4331	char *			my_file2_pathp = NULL;
4332	ssize_t			my_result;
4333	char			my_buffer[16];
4334	struct statfs	my_statfs_buf;
4335	kern_return_t           my_kr;
4336
4337	/* need to know type of file system */
4338	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4339	if ( my_err == -1 ) {
4340		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4341		goto test_failed_exit;
4342	}
4343	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4344		/* ufs does not support exchangedata */
4345		my_err = 0;
4346		goto test_passed_exit;
4347	}
4348
4349        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file1_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4350        if(my_kr != KERN_SUCCESS){
4351                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4352                goto test_failed_exit;
4353        }
4354
4355	*my_file1_pathp = 0x00;
4356	strcat( my_file1_pathp, &g_target_path[0] );
4357	strcat( my_file1_pathp, "/" );
4358
4359	/* create a test file */
4360	my_err = create_random_name( my_file1_pathp, 1 );
4361	if ( my_err != 0 ) {
4362		printf( "create_random_name my_err: %d\n", my_err );
4363		goto test_failed_exit;
4364	}
4365	my_fd1 = open( my_file1_pathp, O_RDWR, 0 );
4366	if ( my_fd1 == -1 ) {
4367		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4368		goto test_failed_exit;
4369	}
4370	my_result = write( my_fd1, "11111111", 8 );
4371	if ( my_result == -1 ) {
4372		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4373		goto test_failed_exit;
4374	}
4375
4376        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file2_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4377        if(my_kr != KERN_SUCCESS){
4378                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4379                goto test_failed_exit;
4380        }
4381
4382	*my_file2_pathp = 0x00;
4383	strcat( my_file2_pathp, &g_target_path[0] );
4384	strcat( my_file2_pathp, "/" );
4385
4386	/* create a test file */
4387	my_err = create_random_name( my_file2_pathp, 1 );
4388	if ( my_err != 0 ) {
4389		printf( "create_random_name my_err: %d\n", my_err );
4390		goto test_failed_exit;
4391	}
4392	my_fd2 = open( my_file2_pathp, O_RDWR, 0 );
4393	if ( my_fd2 == -1 ) {
4394		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4395		goto test_failed_exit;
4396	}
4397	my_result = write( my_fd2, "22222222", 8 );
4398	if ( my_result == -1 ) {
4399		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4400		goto test_failed_exit;
4401	}
4402	close(my_fd1);
4403	my_fd1 = -1;
4404	close(my_fd2);
4405	my_fd2 = -1;
4406
4407	/* test exchangedata */
4408	my_err = exchangedata( my_file1_pathp, my_file2_pathp, 0 );
4409	if ( my_err == -1 ) {
4410		printf( "exchangedata failed with error %d - \"%s\" \n", errno, strerror( errno) );
4411		goto test_failed_exit;
4412	}
4413
4414	/* now validate exchange */
4415	my_fd1 = open( my_file1_pathp, O_RDONLY, 0 );
4416	if ( my_fd1 == -1 ) {
4417		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4418		goto test_failed_exit;
4419	}
4420	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
4421	my_result = read( my_fd1, &my_buffer[0], 8 );
4422	if ( my_result == -1 ) {
4423		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4424		goto test_failed_exit;
4425	}
4426
4427	if ( memcmp( &my_buffer[0], "22222222", 8 ) != 0 ) {
4428		printf( "exchangedata failed - incorrect data in file \n" );
4429		goto test_failed_exit;
4430	}
4431
4432	my_err = 0;
4433	goto test_passed_exit;
4434
4435test_failed_exit:
4436	my_err = -1;
4437
4438test_passed_exit:
4439	if ( my_fd1 != -1 )
4440		close( my_fd1 );
4441	if ( my_file1_pathp != NULL ) {
4442		remove( my_file1_pathp );
4443		vm_deallocate(mach_task_self(), (vm_address_t)my_file1_pathp, PATH_MAX);
4444	 }
4445	if ( my_fd2 != -1 )
4446		close( my_fd2 );
4447	if ( my_file2_pathp != NULL ) {
4448		remove( my_file2_pathp );
4449		vm_deallocate(mach_task_self(), (vm_address_t)my_file2_pathp, PATH_MAX);
4450	 }
4451	return( my_err );
4452}
4453
4454
4455/*  **************************************************************************************************************
4456 *	Test searchfs system calls.
4457 *  **************************************************************************************************************
4458 */
4459
4460struct packed_name_attr {
4461    u_int32_t	            size;	/* Of the remaining fields */
4462    struct attrreference	ref;	/* Offset/length of name itself */
4463    char 			        name[  PATH_MAX ];
4464};
4465
4466struct packed_attr_ref {
4467    u_int32_t    		    size;	/* Of the remaining fields */
4468    struct attrreference	ref;	/* Offset/length of attr itself */
4469};
4470
4471struct packed_result {
4472    u_int32_t	        size;		/* Including size field itself */
4473    attrreference_t     obj_name;
4474    struct fsobj_id	    obj_id;
4475    struct timespec     obj_create_time;
4476    char                room_for_name[ 64 ];
4477};
4478typedef struct packed_result packed_result;
4479typedef struct packed_result * packed_result_p;
4480
4481#define MAX_MATCHES	10
4482#define MAX_EBUSY_RETRIES 5
4483
4484int searchfs_test( void * the_argp )
4485{
4486#if !TARGET_OS_EMBEDDED
4487	int						my_err, my_items_found = 0, my_ebusy_count;
4488	char *					my_pathp = NULL;
4489    unsigned long			my_matches;
4490    unsigned long			my_search_options;
4491    struct fssearchblock	my_search_blk;
4492    struct attrlist			my_return_list;
4493    struct searchstate		my_search_state;
4494    struct packed_name_attr	my_info1;
4495    struct packed_attr_ref	my_info2;
4496    packed_result			my_result_buffer[ MAX_MATCHES ];
4497	struct statfs			my_statfs_buf;
4498	kern_return_t           my_kr;
4499
4500	/* need to know type of file system */
4501	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4502	if ( my_err == -1 ) {
4503		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4504		goto test_failed_exit;
4505	}
4506	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4507		/* ufs does not support exchangedata */
4508		my_err = 0;
4509		goto test_passed_exit;
4510	}
4511
4512        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4513        if(my_kr != KERN_SUCCESS){
4514                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4515                goto test_failed_exit;
4516        }
4517
4518	*my_pathp = 0x00;
4519	strcat( my_pathp, &g_target_path[0] );
4520	strcat( my_pathp, "/" );
4521
4522	/* create test files */
4523	my_err = create_file_with_name( my_pathp, "foo", 0 );
4524	if ( my_err < 0 ) {
4525		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4526		goto test_failed_exit;
4527	}
4528
4529	my_err = create_file_with_name( my_pathp, "foobar", 0 );
4530	if ( my_err < 0 ) {
4531		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4532		goto test_failed_exit;
4533	}
4534
4535	my_err = create_file_with_name( my_pathp, "foofoo", 0 );
4536	if ( my_err < 0 ) {
4537		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4538		goto test_failed_exit;
4539	}
4540
4541	my_err = create_file_with_name( my_pathp, "xxxfoo", 0 );
4542	if ( my_err < 0 ) {
4543		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4544		goto test_failed_exit;
4545	}
4546
4547    /* EBUSY count  updated below the catalogue_changed label */
4548    my_ebusy_count = 0;
4549
4550catalogue_changed:
4551	/* search target volume for all file system objects with "foo" in the name */
4552    /* Set up the attributes we're searching on. */
4553    my_items_found = 0; /* Set this here in case we're completely restarting */
4554    my_search_blk.searchattrs.bitmapcount = ATTR_BIT_MAP_COUNT;
4555    my_search_blk.searchattrs.reserved = 0;
4556    my_search_blk.searchattrs.commonattr = ATTR_CMN_NAME;
4557    my_search_blk.searchattrs.volattr = 0;
4558    my_search_blk.searchattrs.dirattr = 0;
4559    my_search_blk.searchattrs.fileattr = 0;
4560    my_search_blk.searchattrs.forkattr = 0;
4561
4562    /* Set up the attributes we want for all returned matches. */
4563    /* Why is returnattrs a pointer instead of an embedded struct? */
4564    my_search_blk.returnattrs = &my_return_list;
4565    my_return_list.bitmapcount = ATTR_BIT_MAP_COUNT;
4566    my_return_list.reserved = 0;
4567    my_return_list.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJID | ATTR_CMN_CRTIME;
4568    my_return_list.volattr = 0;
4569    my_return_list.dirattr = 0;
4570    my_return_list.fileattr = 0;
4571    my_return_list.forkattr = 0;
4572
4573    /* Allocate a buffer for returned matches */
4574    my_search_blk.returnbuffer = my_result_buffer;
4575    my_search_blk.returnbuffersize = sizeof(my_result_buffer);
4576
4577    /* Pack the searchparams1 into a buffer */
4578    /* NOTE: A name appears only in searchparams1 */
4579    strcpy( my_info1.name, "foo" );
4580    my_info1.ref.attr_dataoffset = sizeof(struct attrreference);
4581    my_info1.ref.attr_length = strlen(my_info1.name) + 1;
4582    my_info1.size = sizeof(struct attrreference) + my_info1.ref.attr_length;
4583    my_search_blk.searchparams1 = &my_info1;
4584    my_search_blk.sizeofsearchparams1 = my_info1.size + sizeof(u_int32_t);
4585
4586    /* Pack the searchparams2 into a buffer */
4587    my_info2.size = sizeof(struct attrreference);
4588    my_info2.ref.attr_dataoffset = sizeof(struct attrreference);
4589    my_info2.ref.attr_length = 0;
4590    my_search_blk.searchparams2 = &my_info2;
4591    my_search_blk.sizeofsearchparams2 = sizeof(my_info2);
4592
4593    /* Maximum number of matches we want */
4594    my_search_blk.maxmatches = MAX_MATCHES;
4595
4596    /* Maximum time to search, per call */
4597    my_search_blk.timelimit.tv_sec = 1;
4598    my_search_blk.timelimit.tv_usec = 0;
4599
4600    my_search_options = (SRCHFS_START | SRCHFS_MATCHPARTIALNAMES |
4601						 SRCHFS_MATCHFILES | SRCHFS_MATCHDIRS);
4602	do {
4603		char *  my_end_ptr;
4604		char *	my_ptr;
4605		int		i;
4606
4607		my_err = searchfs( my_pathp, &my_search_blk, &my_matches, 0, my_search_options, &my_search_state );
4608        if ( my_err == -1 )
4609            my_err = errno;
4610        if ( (my_err == 0 || my_err == EAGAIN) && my_matches > 0 ) {
4611            /* Unpack the results */
4612          //  printf("my_matches %d \n", my_matches);
4613            my_ptr = (char *) &my_result_buffer[0];
4614            my_end_ptr = (my_ptr + sizeof(my_result_buffer));
4615            for ( i = 0; i < my_matches; ++i ) {
4616                packed_result_p		my_result_p = (packed_result_p) my_ptr;
4617				char *				my_name_p;
4618
4619				/* see if we foound all our test files */
4620				my_name_p = (((char *)(&my_result_p->obj_name)) + my_result_p->obj_name.attr_dataoffset);
4621				if ( memcmp( my_name_p, "foo", 3 ) == 0 ||
4622					 memcmp( my_name_p, "foobar", 6 ) == 0 ||
4623					 memcmp( my_name_p, "foofoo", 6 ) == 0 ||
4624					 memcmp( my_name_p, "xxxfoo", 6 ) == 0 ) {
4625					my_items_found++;
4626				}
4627#if DEBUG
4628                printf("obj_name \"%.*s\" \n",
4629                    (int) my_result_p->obj_name.attr_length,
4630                    (((char *)(&my_result_p->obj_name)) +
4631                     my_result_p->obj_name.attr_dataoffset));
4632                printf("size %d fid_objno %d fid_generation %d tv_sec 0x%02LX \n",
4633                    my_result_p->size, my_result_p->obj_id.fid_objno,
4634                    my_result_p->obj_id.fid_generation,
4635                    my_result_p->obj_create_time.tv_sec);
4636#endif
4637                my_ptr = (my_ptr + my_result_p->size);
4638                if (my_ptr > my_end_ptr)
4639                    break;
4640            }
4641        }
4642
4643	/* EBUSY indicates catalogue change; retry a few times. */
4644	if ((my_err == EBUSY) && (my_ebusy_count++ < MAX_EBUSY_RETRIES)) {
4645		goto catalogue_changed;
4646	}
4647	if ( !(my_err == 0 || my_err == EAGAIN) ) {
4648		printf( "searchfs failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4649	}
4650	my_search_options &= ~SRCHFS_START;
4651    } while ( my_err == EAGAIN );
4652
4653	if ( my_items_found < 4 ) {
4654		printf( "searchfs failed to find all test files \n" );
4655		goto test_failed_exit;
4656	}
4657
4658	my_err = 0;
4659	goto test_passed_exit;
4660
4661test_failed_exit:
4662	my_err = -1;
4663
4664test_passed_exit:
4665	if ( my_pathp != NULL ) {
4666		char *   my_ptr = (my_pathp + strlen( my_pathp ));
4667		strcat( my_pathp, "foo" );
4668		remove( my_pathp );
4669		*my_ptr = 0x00;
4670		strcat( my_pathp, "foobar" );
4671		remove( my_pathp );
4672		*my_ptr = 0x00;
4673		strcat( my_pathp, "foofoo" );
4674		remove( my_pathp );
4675		*my_ptr = 0x00;
4676		strcat( my_pathp, "xxxfoo" );
4677		remove( my_pathp );
4678		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4679	 }
4680	return( my_err );
4681#else
4682	printf( "\t--> Not supported on EMBEDDED TARGET\n" );
4683	return 0;
4684#endif
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#if !TARGET_OS_EMBEDDED
4970	int					my_err;
4971	int					my_msg_queue_id = -1;
4972	ssize_t				my_result;
4973	struct msqid_ds		my_msq_ds;
4974	struct testing_msq_message {
4975		long	msq_type;
4976		char	msq_buffer[ 32 ];
4977	}					my_msg;
4978
4979	/* get a message queue established for our use */
4980	my_msg_queue_id = msgget( IPC_PRIVATE, (IPC_CREAT | IPC_EXCL | IPC_R | IPC_W) );
4981	if ( my_msg_queue_id == -1 ) {
4982		printf( "msgget failed with errno %d - %s \n", errno, strerror( errno ) );
4983		goto test_failed_exit;
4984	}
4985
4986	/* get some stats on our message queue */
4987	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
4988	if ( my_err == -1 ) {
4989		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
4990		goto test_failed_exit;
4991	}
4992	if ( my_msq_ds.msg_perm.cuid != geteuid( ) ) {
4993		printf( "msgctl IPC_STAT failed to get correct creator uid \n" );
4994		goto test_failed_exit;
4995	}
4996	if ( (my_msq_ds.msg_perm.mode & (IPC_R | IPC_W)) == 0 ) {
4997		printf( "msgctl IPC_STAT failed to get correct mode \n" );
4998		goto test_failed_exit;
4999	}
5000
5001	/* put a message into our queue */
5002	my_msg.msq_type = 1;
5003	strcpy( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" );
5004	my_err = msgsnd( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0 );
5005	if ( my_err == -1 ) {
5006		printf( "msgsnd failed with errno %d - %s \n", errno, strerror( errno ) );
5007		goto test_failed_exit;
5008	}
5009
5010	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
5011	if ( my_err == -1 ) {
5012		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
5013		goto test_failed_exit;
5014	}
5015	if ( my_msq_ds.msg_qnum != 1 ) {
5016		printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5017		goto test_failed_exit;
5018	}
5019
5020	/* pull message off the queue */
5021	bzero( (void *)&my_msg, sizeof( my_msg ) );
5022	my_result = msgrcv( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0, 0 );
5023	if ( my_result == -1 ) {
5024		printf( "msgrcv failed with errno %d - %s \n", errno, strerror( errno ) );
5025		goto test_failed_exit;
5026	}
5027	if ( my_result != sizeof( my_msg.msq_buffer ) ) {
5028		printf( "msgrcv failed to return the correct number of bytes in our buffer \n" );
5029		goto test_failed_exit;
5030	}
5031	if ( strcmp( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ) != 0 ) {
5032		printf( "msgrcv failed to get the correct message \n" );
5033		goto test_failed_exit;
5034	}
5035
5036	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
5037	if ( my_err == -1 ) {
5038		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
5039		goto test_failed_exit;
5040	}
5041	if ( my_msq_ds.msg_qnum != 0 ) {
5042		printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5043		goto test_failed_exit;
5044	}
5045
5046	/* tear down the message queue */
5047	my_err = msgctl( my_msg_queue_id, IPC_RMID, NULL );
5048	if ( my_err == -1 ) {
5049		printf( "msgctl IPC_RMID failed with errno %d - %s \n", errno, strerror( errno ) );
5050		goto test_failed_exit;
5051	}
5052	my_msg_queue_id = -1;
5053
5054	my_err = 0;
5055	goto test_passed_exit;
5056
5057test_failed_exit:
5058	my_err = -1;
5059
5060test_passed_exit:
5061	if ( my_msg_queue_id != -1 ) {
5062		msgctl( my_msg_queue_id, IPC_RMID, NULL );
5063	}
5064	return( my_err );
5065#else
5066	printf( "\t--> Not supported on EMBEDDED TARGET \n" );
5067	return 0;
5068#endif
5069}
5070
5071
5072
5073/*  **************************************************************************************************************
5074 *	Test execution from data and stack areas.
5075 *  **************************************************************************************************************
5076 */
5077int data_exec_tests( void * the_argp )
5078{
5079	int my_err = 0;
5080	int arch, bits;
5081	posix_spawnattr_t attrp;
5082	char *argv[] = { "helpers/data_exec32nonxspawn", NULL };
5083
5084	int my_pid, my_status, ret;
5085
5086	if ((arch = get_architecture()) == -1) {
5087		printf("data_exec_test: couldn't determine architecture\n");
5088		goto test_failed_exit;
5089	}
5090
5091	bits = get_bits();
5092
5093	/*
5094	 * If the machine is 64-bit capable, run both the 32 and 64 bit versions of the test.
5095	 * Otherwise, just run the 32-bit version.
5096	 */
5097
5098	if (arch == INTEL) {
5099		if (bits == 64) {
5100			if (system("arch -arch x86_64 helpers/data_exec") != 0) {
5101				printf("data_exec-x86_64 failed\n");
5102				goto test_failed_exit;
5103			}
5104		}
5105
5106		if (system("arch -arch i386 helpers/data_exec") != 0) {
5107			printf("data_exec-i386 failed\n");
5108			goto test_failed_exit;
5109		}
5110
5111		posix_spawnattr_init(&attrp);
5112		posix_spawnattr_setflags(&attrp, _POSIX_SPAWN_ALLOW_DATA_EXEC );
5113		ret = posix_spawn(&my_pid, "helpers/data_exec32nonxspawn", NULL, &attrp, argv, NULL);
5114		if (ret) {
5115			printf("data_exec-i386 failed in posix_spawn %s\n", strerror(errno));
5116			goto test_failed_exit;
5117		}
5118		ret = wait4(my_pid, &my_status, 0, NULL);
5119		if (ret == -1) {
5120			printf("data_exec-i386 wait4 failed with errno %d - %s\n", errno, strerror(errno));
5121			goto test_failed_exit;
5122		}
5123		if (WEXITSTATUS(my_status) != 0) {
5124			printf("data_exec-i386 _POSIX_SPAWN_ALLOW_DATA_EXEC failed\n");
5125			goto test_failed_exit;
5126		}
5127	}
5128
5129	/* Add new architectures here similar to the above. */
5130
5131	goto test_passed_exit;
5132
5133test_failed_exit:
5134	my_err = -1;
5135
5136test_passed_exit:
5137	return my_err;
5138}
5139
5140/*  **************************************************************************************************************
5141 *	Test KASLR-related functionality
5142 *  **************************************************************************************************************
5143 */
5144int kaslr_test( void * the_argp )
5145{
5146	int result = 0;
5147	uint64_t slide = 0;
5148	size_t size;
5149	int slide_enabled;
5150
5151	size = sizeof(slide_enabled);
5152	result = sysctlbyname("kern.slide", &slide_enabled, &size, NULL, 0);
5153	if (result != 0) {
5154		printf("sysctlbyname(\"kern.slide\") failed with errno %d\n", errno);
5155		goto test_failed_exit;
5156	}
5157
5158	/* Test positive case first */
5159	size = sizeof(slide);
5160	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size);
5161	if (result == 0) {
5162		/* syscall supported, slide must be non-zero if running latest xnu and KASLR is enabled */
5163		if (slide_enabled && (slide == 0)) {
5164			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported slide of 0x%016llx\n", slide);
5165			goto test_failed_exit;
5166		}
5167		if (size != sizeof(slide)) {
5168			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported size of %lu\n", size);
5169			goto test_failed_exit;
5170		}
5171	} else {
5172		/* Only ENOTSUP is allowed. If so, assume all calls will be unsupported */
5173		if (errno == ENOTSUP) {
5174			return 0;
5175		} else {
5176			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) returned unexpected errno (errno %d)\n", errno);
5177			goto test_failed_exit;
5178		}
5179	}
5180
5181	/* Negative cases for expected failures */
5182	size = sizeof(slide);
5183	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, &size);
5184	if ((result == 0) || (errno != EFAULT)) {
5185		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5186		goto test_failed_exit;
5187	}
5188
5189	size = sizeof(slide) + 1; /* EINVAL */
5190	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size);
5191	if ((result == 0) || (errno != EINVAL)) {
5192		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size+1) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5193		goto test_failed_exit;
5194	}
5195
5196	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, NULL /* EFAULT */);
5197	if ((result == 0) || (errno != EFAULT)) {
5198		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, NULL) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5199		goto test_failed_exit;
5200	}
5201
5202	size = sizeof(slide);
5203	result = kas_info(KAS_INFO_MAX_SELECTOR /* EINVAL */, &slide, &size);
5204	if ((result == 0) || (errno != EINVAL)) {
5205		printf("kas_info(KAS_INFO_MAX_SELECTOR, &slide, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5206		goto test_failed_exit;
5207	}
5208
5209	return 0;
5210
5211test_failed_exit:
5212	return -1;
5213}
5214
5215#if TEST_SYSTEM_CALLS
5216
5217/*  **************************************************************************************************************
5218 *	Test xxxxxxxxx system calls.
5219 *  **************************************************************************************************************
5220 */
5221int sample_test( void * the_argp )
5222{
5223	int			my_err;
5224	int			my_fd = -1;
5225	char *		my_pathp = NULL;
5226	kern_return_t           my_kr;
5227
5228        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5229        if(my_kr != KERN_SUCCESS){
5230                  printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5231                  goto test_failed_exit;
5232        }
5233
5234	*my_pathp = 0x00;
5235	strcat( my_pathp, &g_target_path[0] );
5236	strcat( my_pathp, "/" );
5237
5238	/* create a test file */
5239	my_err = create_random_name( my_pathp, 1 );
5240	if ( my_err != 0 ) {
5241		goto test_failed_exit;
5242	}
5243
5244	/* add your test code here... */
5245
5246
5247	my_err = 0;
5248	goto test_passed_exit;
5249
5250test_failed_exit:
5251	my_err = -1;
5252
5253test_passed_exit:
5254	if ( my_fd != -1 )
5255		close( my_fd );
5256	if ( my_pathp != NULL ) {
5257		remove( my_pathp );
5258		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
5259	 }
5260	return( my_err );
5261}
5262
5263#endif
5264