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 if( my_new_gid1 != my_groups[ i ] ) {
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#if !TARGET_OS_EMBEDDED
1762		/*
1763		 * test to make sure setaudit_addr doesn't cause audit info to get lost from
1764		 * the credential.
1765		 */
1766		bzero( &my_aia, sizeof(my_aia) );
1767		my_aia.ai_auid = 442344;
1768		my_aia.ai_asid = AU_ASSIGN_ASID;
1769		my_aia.ai_termid.at_type = AU_IPv4;
1770		my_err = setaudit_addr( &my_aia, sizeof(my_aia) );
1771		if (my_err != 0) {
1772			printf( "setaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1773			exit( -1 );
1774		}
1775
1776		my_aia.ai_auid = 0;
1777		my_err = getaudit_addr( &my_aia, sizeof(my_aia) );
1778		if (my_err != 0) {
1779			printf( "getaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1780			exit( -1 );
1781		}
1782		//printf("new audit ID is %d \n", my_aia.ai_auid);
1783
1784		if (my_aia.ai_auid != 442344) {
1785			printf("test failed - wrong audit ID was set - %d \n", my_aia.ai_auid);
1786			exit( -1 );
1787		}
1788#endif
1789
1790		/* change real uid and effective uid to current euid */
1791		my_err = setuid( my_euid );
1792		if ( my_err == -1 ) {
1793			printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1794			exit( -1 );
1795		}
1796		if ( getuid( ) != my_euid ) {
1797			printf( "setuid call failed to set the real uid \n" );
1798			exit( -1 );
1799		}
1800
1801		/* change effective uid to current euid - really a NOP */
1802		my_err = seteuid( my_euid );
1803		if ( my_err == -1 ) {
1804			printf( "seteuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1805			exit( -1 );
1806		}
1807		if ( geteuid( ) != my_euid ) {
1808			printf( "seteuid call failed to set the original euid \n" );
1809			exit( -1 );
1810		}
1811
1812		/* change real uid and effective uid to original real uid */
1813		my_err = setuid( my_ruid );
1814		if ( my_err == -1 ) {
1815			printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1816			exit( -1 );
1817		}
1818		if ( getuid( ) != my_ruid ) {
1819			printf( "setuid call failed to set the real uid \n" );
1820			exit( -1 );
1821		}
1822
1823		exit(0);
1824	}
1825
1826	/*
1827	 * parent process -
1828	 * wait for child to exit
1829	 */
1830	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
1831	if ( my_wait_pid == -1 ) {
1832		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
1833		goto test_failed_exit;
1834	}
1835
1836	/* wait4 should return our child's pid when it exits */
1837	if ( my_wait_pid != my_pid ) {
1838		printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
1839		goto test_failed_exit;
1840	}
1841
1842	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
1843		printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
1844		goto test_failed_exit;
1845	}
1846
1847	my_err = 0;
1848	goto test_passed_exit;
1849
1850test_failed_exit:
1851	my_err = -1;
1852
1853test_passed_exit:
1854	return( my_err );
1855}
1856
1857/*  **************************************************************************************************************
1858 *	Test mknod, sync system calls.
1859 *  **************************************************************************************************************
1860 */
1861int mknod_sync_test( void * the_argp )
1862{
1863	int			my_err;
1864	char *	my_pathp =      NULL;
1865	kern_return_t           my_kr;
1866
1867	if ( g_skip_setuid_tests != 0 ) {
1868		printf("\t skipping this test \n");
1869		my_err = 0;
1870		goto test_passed_exit;
1871	}
1872
1873        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1874        if(my_kr != KERN_SUCCESS){
1875                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1876                goto test_failed_exit;
1877        }
1878
1879	*my_pathp = 0x00;
1880	strcat( my_pathp, "/dev/" );
1881
1882	/* get a unique name for our test file */
1883	my_err = create_random_name( my_pathp, 0 );
1884	if ( my_err != 0 ) {
1885		goto test_failed_exit;
1886	}
1887
1888	my_err = mknod( my_pathp, (S_IFCHR | S_IRWXU), 0 );
1889	if ( my_err == -1 ) {
1890		printf( "mknod failed with errno %d - %s \n", errno, strerror( errno ) );
1891		printf( "path \"%s\" \n", my_pathp );
1892		goto test_failed_exit;
1893	}
1894
1895	/* not really sure what to do with sync call test */
1896	sync( );
1897	my_err = 0;
1898	goto test_passed_exit;
1899
1900test_failed_exit:
1901	my_err = -1;
1902
1903test_passed_exit:
1904	if ( my_pathp != NULL ) {
1905		remove( my_pathp );
1906		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1907	 }
1908	return( my_err );
1909}
1910
1911/*  **************************************************************************************************************
1912 *	Test chflags, fchflags system calls.
1913 *  **************************************************************************************************************
1914 */
1915int chflags_fchflags_test( void * the_argp )
1916{
1917	int				my_err;
1918	int				my_fd = -1;
1919	u_int			my_flags;
1920	char *			my_pathp = NULL;
1921	struct stat		my_sb;
1922	kern_return_t           my_kr;
1923
1924        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1925        if(my_kr != KERN_SUCCESS){
1926                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1927                goto test_failed_exit;
1928        }
1929
1930	*my_pathp = 0x00;
1931	strcat( my_pathp, &g_target_path[0] );
1932	strcat( my_pathp, "/" );
1933
1934	/* create a test file */
1935	my_err = create_random_name( my_pathp, 1 );
1936	if ( my_err != 0 ) {
1937		goto test_failed_exit;
1938	}
1939
1940	/* make test file unchangable */
1941	my_err = stat( my_pathp, &my_sb );
1942	if ( my_err != 0 ) {
1943		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1944		goto test_failed_exit;
1945	}
1946
1947	my_flags = (my_sb.st_flags | UF_IMMUTABLE);
1948	my_err = chflags( my_pathp, my_flags );
1949	if ( my_err != 0 ) {
1950		printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1951		goto test_failed_exit;
1952	}
1953
1954	/* should fail with EPERM since we cannot change the file now */
1955	my_fd = open( my_pathp, O_RDWR, 0 );
1956	if ( my_fd == -1 && errno != EPERM ) {
1957		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1958		printf( "open failed with wrong error - should be EPERM \n" );
1959		goto test_failed_exit;
1960	}
1961
1962	/* this open should work OK */
1963	my_fd = open( my_pathp, O_RDONLY, 0 );
1964	if ( my_fd == -1 ) {
1965		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1966		goto test_failed_exit;
1967	}
1968
1969	my_err = stat( my_pathp, &my_sb );
1970	if ( my_err != 0 ) {
1971		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1972		goto test_failed_exit;
1973	}
1974
1975	my_flags = (my_sb.st_flags & ~UF_IMMUTABLE);
1976	my_err = fchflags( my_fd, my_flags );
1977	if ( my_err != 0 ) {
1978		printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1979		goto test_failed_exit;
1980	}
1981
1982	close( my_fd );
1983	my_fd = -1;
1984
1985	/* should now work */
1986	my_fd = open( my_pathp, O_RDWR, 0 );
1987	if ( my_fd == -1 ) {
1988		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1989		goto test_failed_exit;
1990	}
1991
1992	my_err = 0;
1993	goto test_passed_exit;
1994
1995test_failed_exit:
1996	my_err = -1;
1997
1998test_passed_exit:
1999	if ( my_fd != -1 )
2000		close( my_fd );
2001	if ( my_pathp != NULL ) {
2002		remove( my_pathp );
2003		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2004	 }
2005	return( my_err );
2006}
2007
2008
2009/*  **************************************************************************************************************
2010 *	Test kill, vfork, execve system calls.
2011 *  **************************************************************************************************************
2012 */
2013/*  There are many new exec() situations to test now that 64-bit is in. These extra tests are in response to
2014 * rdar://4606399 and rdar://4607285. It should cover every permutation of the following variables.
2015 *
2016 *  - Current Process "Bitness": 			64 or 32
2017 *  - exec()'ed process "bitness": 			64 or 32
2018 *  	(if 64 bit, size of page zero:)			(4GB or 4KB)
2019 *  - Parent Process "Bitness":				64 or 32
2020
2021 *  Test to make sure certain inheritance properties of fork()'ed children
2022 * are correctly set.
2023 *  1. 64 bit process forking() 64-bit child, child execing() 64-bit file (4GB pagezero)
2024 *  2. 64 bit process forking() 64-bit child, child execing() 64-bit file (4KB pagezero)
2025 *  3. 64 bit process forking() 64-bit child, child execing() 32-bit file
2026 *  4. 32 bit process forking() 32-bit child, child execing() 32-bit file
2027 *  5. 32 bit process forking() 32-bit child, child execing() 64 bit file (4GB pagezero)
2028 *  6. 32 bit process forking() 32-bit child, child execing() 64 bit file (4KB pagezero)
2029 *
2030 */
2031
2032
2033int execve_kill_vfork_test( void * the_argp )
2034{
2035	int	my_err, my_status;
2036	pid_t	my_pid, my_wait_pid;
2037	char *	errmsg = NULL;
2038	char * argvs[2] = {"", NULL};
2039	int bits = get_bits();		/* Gets actual processor bit-ness. */
2040
2041	if (bits != 32 && bits != 64) {
2042		printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits());
2043		return(-1);
2044	}
2045
2046	if (get_architecture() == -1) {
2047		errmsg = "get_architecture() could not determine the CPU architecture.\n";
2048		goto test_failed_exit;
2049	}
2050
2051	if (get_architecture() == INTEL) {
2052		struct stat sb;
2053
2054		if (bits == 64 && sizeof(long) == 8) {
2055			/*
2056			 * Running on x86_64 hardware and running in 64-bit mode.
2057			 * Check cases 1, 2, 3 and fork a child to check 4, 5, 6.
2058			 */
2059			errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4G pagezero.\n";
2060			argvs[0] = "sleep-x86_64-4G";
2061			if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 1))		goto test_failed_exit;
2062
2063			errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4K Pagezero.\n";
2064			argvs[0] = "sleep-x86_64-4K";
2065			if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 1))		goto test_failed_exit;
2066
2067			errmsg = "execve failed: from x64_64 forking and exec()ing 32-bit i386 process.\n";
2068			argvs[0] = "sleep-i386";
2069			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1))		goto test_failed_exit;
2070
2071			/* Fork off a helper process and load a 32-bit program in it to test 32->64 bit exec(). */
2072			errmsg = "execve failed to exec the helper process.\n";
2073			argvs[0] = "launch-i386";
2074			if (do_execve_test("helpers/launch-i386", argvs, NULL, 1) != 0)		goto test_failed_exit;
2075
2076			/* Test posix_spawn for i386, x86_64 (should succeed) */
2077			errmsg = NULL;
2078			if (do_spawn_test(CPU_TYPE_I386, 0))
2079				goto test_failed_exit;
2080			if (do_spawn_test(CPU_TYPE_X86_64, 0))
2081				goto test_failed_exit;
2082		}
2083		else if (bits == 64 && sizeof(long) == 4) {
2084			/*
2085			 * Running on x86_64 hardware, but actually running in 32-bit mode.
2086			 * Check cases 4, 5, 6 and fork a child to check 1, 2, 3.
2087			 */
2088			errmsg = "execve failed: from i386 forking and exec()ing i386 process.\n";
2089			argvs[0] = "sleep-i386";
2090			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 0))		goto test_failed_exit;
2091
2092			errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4G pagezero.\n";
2093			argvs[0] = "sleep-x86_64-4G";
2094			if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 0))		goto test_failed_exit;
2095
2096			errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4K pagezero.\n";
2097			argvs[0] = "sleep-x86_64-4K";
2098			if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 0))		goto test_failed_exit;
2099
2100			/* Fork off a helper process and load a 64-bit program in it to test 64->32 bit exec(). */
2101			errmsg = "execve failed to exec the helper process.\n";
2102			argvs[0] = "launch-x86_64";
2103			if (do_execve_test("helpers/launch-x86_64", argvs, NULL, 1) != 0)	goto test_failed_exit;
2104
2105			/* Test posix_spawn for i386, x86_64 (should succeed) */
2106			errmsg = NULL;
2107			if (do_spawn_test(CPU_TYPE_I386, 0))
2108				goto test_failed_exit;
2109			if (do_spawn_test(CPU_TYPE_X86_64, 0))
2110				goto test_failed_exit;
2111		}
2112		else if (bits == 32) {
2113			/* Running on i386 hardware. Check cases 4. */
2114			errmsg = "execve failed: from i386 forking and exec()ing 32-bit i386 process.\n";
2115			argvs[0] = "sleep-i386";
2116			if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) 		goto test_failed_exit;
2117
2118			/* Test posix_spawn for x86_64 (should fail), i386 (should succeed) */
2119			errmsg = NULL;
2120			if (do_spawn_test(CPU_TYPE_X86_64, 1))
2121				goto test_failed_exit;
2122			if (do_spawn_test(CPU_TYPE_I386, 0))
2123				goto test_failed_exit;
2124		}
2125	} else if(get_architecture() == ARM) {
2126
2127		errmsg = "execve failed: from arm forking and exec()ing 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 ( WIFSIGNALED( my_status ) || ( 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	int		acct_record_found;
2871	char *		test_bin_name = NULL;
2872
2873	if ( g_skip_setuid_tests != 0 ) {
2874		printf("\t skipping this test \n");
2875		my_err = 0;
2876		goto test_passed_exit;
2877	}
2878
2879	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2880        if(my_kr != KERN_SUCCESS){
2881                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2882                goto test_failed_exit;
2883        }
2884
2885	*my_pathp = 0x00;
2886	strcat( my_pathp, &g_target_path[0] );
2887	strcat( my_pathp, "/" );
2888
2889	/* create a test file */
2890	my_err = create_random_name( my_pathp, 1 );
2891	if ( my_err != 0 ) {
2892		goto test_failed_exit;
2893	}
2894
2895	/* enable process accounting */
2896	my_err =  acct( my_pathp );
2897	if ( my_err == -1 ) {
2898		printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2899		goto test_failed_exit;
2900	}
2901
2902	/*
2903	 * spin off a child process that we will use for testing.
2904	 */
2905	my_pid = fork( );
2906	if ( my_pid == -1 ) {
2907		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2908		goto test_failed_exit;
2909	}
2910	if ( my_pid == 0 ) {
2911		char *argv[2];		/* supply valid argv array to execv() */
2912		argv[0] = "/usr/bin/true";
2913		argv[1] = 0;
2914
2915		/*
2916		 * child process - do a little work then exit.
2917		 */
2918		my_err = execv( argv[0], argv);
2919		exit( 0 );
2920	}
2921
2922	/* parent process -
2923	 * wait for child to exit
2924	 */
2925	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2926	if ( my_wait_pid == -1 ) {
2927		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2928		goto test_failed_exit;
2929	}
2930
2931	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2932		printf("unexpected child exit status for accounting test load: %d\n", WEXITSTATUS( my_status));
2933		goto test_failed_exit;
2934	}
2935
2936	/* disable process accounting */
2937	my_err =  acct( NULL );
2938	if ( my_err == -1 ) {
2939		printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2940		goto test_failed_exit;
2941	}
2942
2943	/* now verify that there is accounting info in the log file */
2944	my_fd = open( my_pathp, O_RDONLY, 0 );
2945	if ( my_fd == -1 ) {
2946		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2947		goto test_failed_exit;
2948	}
2949
2950	lseek( my_fd, 0, SEEK_SET );
2951	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
2952	acct_record_found = 0;
2953	test_bin_name = "true";
2954
2955	while(1) {
2956
2957  		my_count = read( my_fd, &my_buffer[0], sizeof(struct acct) );
2958
2959  		if ( my_count == -1 ) {
2960    			printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2961    			goto test_failed_exit;
2962  		}
2963
2964  		if ( my_count < sizeof(struct acct)) {
2965    			/* Indicates EOF or misaligned file size */
2966			printf("Reached end of accounting records with last read count: %d\n", my_count);
2967			break;
2968  		}
2969
2970  		my_acctp = (struct acct *) &my_buffer[0];
2971  		/* first letters in ac_comm should match the name of the executable */
2972  		if ( (getuid() == my_acctp->ac_uid) && (getgid() == my_acctp->ac_gid) &&
2973		     (!strncmp(my_acctp->ac_comm, test_bin_name, strlen(test_bin_name))) ) {
2974    			/* Expected accounting record found */
2975    			acct_record_found = 1;
2976    			break;
2977  		}
2978
2979 	}
2980
2981	if (acct_record_found) {
2982  		my_err = 0;
2983  		goto test_passed_exit;
2984 	} else {
2985   		printf( "------------------------\n" );
2986   		printf( "Expected Accounting Record for child process %s not found\n", test_bin_name );
2987   		printf( "Expected uid: %lu Expected gid: %lu\n" , (unsigned long) getuid(), (unsigned long) getgid() );
2988   		printf( "Account file path: %s\n",  my_pathp );
2989   		goto test_failed_exit;
2990 	}
2991
2992test_failed_exit:
2993	my_err = -1;
2994
2995test_passed_exit:
2996	if ( my_fd != -1 )
2997		close( my_fd );
2998	if ( my_pathp != NULL ) {
2999		remove( my_pathp );
3000		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3001	 }
3002	return( my_err );
3003}
3004
3005void print_acct_debug_strings( char * my_ac_comm )
3006{
3007	char	my_cmd_str[11]; /* sizeof(acct_cmd) + 1 for '\0' if acct_cmd is bogus */
3008	char	my_hex_str[128];
3009	int 	i;
3010
3011	my_hex_str[0] = '\0';
3012	for(i = 0; i < 10; i++)
3013	{
3014		sprintf( my_hex_str, "%s \'0x%x\' ", my_hex_str, my_ac_comm[i]);
3015	}
3016
3017	memccpy(my_cmd_str, my_ac_comm, '\0', 10);
3018	my_cmd_str[10] = '\0'; /* In case ac_comm was bogus */
3019
3020
3021	printf( "my_acctp->ac_comm = \"%s\" (should begin with: \"tr\")\n", my_cmd_str);
3022	printf( "my_acctp->ac_comm = \"%s\"\n", my_hex_str);
3023	printf( "------------------------\n" );
3024}
3025
3026
3027/*  **************************************************************************************************************
3028 *	Test ioctl system calls.
3029 *  **************************************************************************************************************
3030 */
3031int ioctl_test( void * the_argp )
3032{
3033	int					my_err, my_result;
3034	int					my_fd = -1;
3035	struct statfs *		my_infop;
3036	char *				my_ptr;
3037    int					my_blksize;
3038    long long			my_block_count;
3039	char				my_name[ 128 ];
3040
3041	my_result = getmntinfo( &my_infop, MNT_NOWAIT );
3042	if ( my_result < 1 ) {
3043		printf( "getmntinfo failed with error %d - \"%s\" \n", errno, strerror( errno) );
3044		goto test_failed_exit;
3045	}
3046
3047	/* make this a raw device */
3048	strcpy( &my_name[0], &my_infop->f_mntfromname[0] );
3049	if ( (my_ptr = strrchr( &my_name[0], '/' )) != 0 ) {
3050		if ( my_ptr[1] != 'r' ) {
3051			my_ptr[ strlen( my_ptr ) ] = 0x00;
3052			memmove( &my_ptr[2], &my_ptr[1], (strlen( &my_ptr[1] ) + 1) );
3053			my_ptr[1] = 'r';
3054		}
3055	}
3056
3057	my_fd = open(&my_name[0], O_RDONLY );
3058	if ( my_fd == -1 ) {
3059		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3060		goto test_failed_exit;
3061	}
3062
3063    /* obtain the size of the media (in blocks) */
3064	my_err = ioctl( my_fd, DKIOCGETBLOCKCOUNT, &my_block_count );
3065	if ( my_err == -1 ) {
3066		printf( "ioctl DKIOCGETBLOCKCOUNT failed with error %d - \"%s\" \n", errno, strerror( errno) );
3067		goto test_failed_exit;
3068	}
3069
3070    /* obtain the block size of the media */
3071	my_err = ioctl( my_fd, DKIOCGETBLOCKSIZE, &my_blksize );
3072	if ( my_err == -1 ) {
3073		printf( "ioctl DKIOCGETBLOCKSIZE failed with error %d - \"%s\" \n", errno, strerror( errno) );
3074		goto test_failed_exit;
3075	}
3076	//printf( "my_block_count %qd my_blksize %d \n", my_block_count, my_blksize );
3077
3078	/* make sure the returned data looks somewhat valid */
3079	if ( my_blksize < 0 || my_blksize > (1024 * 1000) ) {
3080		printf( "ioctl appears to have returned incorrect block size data \n" );
3081		goto test_failed_exit;
3082	}
3083
3084	my_err = 0;
3085	goto test_passed_exit;
3086
3087test_failed_exit:
3088	my_err = -1;
3089
3090test_passed_exit:
3091	if ( my_fd != -1 )
3092		close( my_fd );
3093	return( my_err );
3094}
3095
3096/*  **************************************************************************************************************
3097 *	Test mkdir, rmdir, umask system calls.
3098 *  **************************************************************************************************************
3099 */
3100int mkdir_rmdir_umask_test( void * the_argp )
3101{
3102	int				my_err;
3103	int				my_fd = -1;
3104	int				did_umask = 0;
3105	char *			my_pathp = NULL;
3106	mode_t			my_orig_mask;
3107	struct stat		my_sb;
3108	kern_return_t           my_kr;
3109
3110        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3111        if(my_kr != KERN_SUCCESS){
3112                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3113                goto test_failed_exit;
3114        }
3115
3116	*my_pathp = 0x00;
3117	strcat( my_pathp, &g_target_path[0] );
3118	strcat( my_pathp, "/" );
3119
3120	/* get a unique name to use with mkdir */
3121	my_err = create_random_name( my_pathp, 0 );
3122	if ( my_err != 0 ) {
3123		printf( "create_random_name failed with error %d\n", my_err );
3124		goto test_failed_exit;
3125	}
3126
3127	/* set umask to clear WX for other and group and clear X for user */
3128	my_orig_mask = umask( (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) );
3129	did_umask = 1;
3130
3131	/* create a directory with RWX for user, group, other (which should be limited by umask) */
3132	my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3133	if ( my_err == -1 ) {
3134		printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3135		goto test_failed_exit;
3136	}
3137
3138	/* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/
3139	my_err = stat( my_pathp, &my_sb );
3140	if ( my_err != 0 ) {
3141		printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3142		goto test_failed_exit;
3143	}
3144	if ( (my_sb.st_mode & (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH)) != 0 ) {
3145		printf( "umask did not limit modes as it should have \n" );
3146		goto test_failed_exit;
3147	}
3148
3149	/* get rid of our test directory */
3150	my_err = rmdir( my_pathp );
3151	if ( my_err == -1 ) {
3152		printf( "rmdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3153		goto test_failed_exit;
3154	}
3155	my_err = 0;
3156	goto test_passed_exit;
3157
3158test_failed_exit:
3159	my_err = -1;
3160
3161test_passed_exit:
3162	if ( my_fd != -1 )
3163		close( my_fd );
3164	if ( my_pathp != NULL ) {
3165		rmdir( my_pathp );
3166		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3167	 }
3168	 if ( did_umask != 0 ) {
3169		umask( my_orig_mask );
3170	 }
3171
3172	return( my_err );
3173}
3174
3175/*  **************************************************************************************************************
3176 *	Test chroot system call.
3177 *  **************************************************************************************************************
3178 */
3179int chroot_test( void * the_argp )
3180{
3181	int			my_err, my_status;
3182	pid_t		my_pid, my_wait_pid;
3183	char *		my_pathp = NULL;
3184	kern_return_t           my_kr;
3185
3186	if ( g_skip_setuid_tests != 0 ) {
3187		printf("\t skipping this test \n");
3188		my_err = 0;
3189		goto test_passed_exit;
3190	}
3191
3192        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3193        if(my_kr != KERN_SUCCESS){
3194                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3195                goto test_failed_exit;
3196        }
3197
3198	*my_pathp = 0x00;
3199	strcat( my_pathp, &g_target_path[0] );
3200	strcat( my_pathp, "/" );
3201
3202	/* get a unique name for our test directory */
3203	my_err = create_random_name( my_pathp, 0 );
3204	if ( my_err != 0 ) {
3205		goto test_failed_exit;
3206	}
3207
3208	/* create a test directory */
3209	my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3210	if ( my_err == -1 ) {
3211		printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3212		goto test_failed_exit;
3213	}
3214
3215	/*
3216	 * spin off a child process that we will use for testing.
3217	 */
3218	my_pid = fork( );
3219	if ( my_pid == -1 ) {
3220		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3221		goto test_failed_exit;
3222	}
3223	if ( my_pid == 0 ) {
3224		/*
3225		 * child process - do getlogin and setlogin testing.
3226		 */
3227		struct stat		my_sb;
3228
3229		/* change our root to our new test directory */
3230		my_err = chroot( my_pathp );
3231		if ( my_err != 0 ) {
3232			printf( "chroot failed with error %d - \"%s\" \n", errno, strerror( errno) );
3233			exit( -1 );
3234		}
3235
3236		/* verify root directory is now an empty directory */
3237		my_err = stat( "/", &my_sb );
3238		if ( my_err != 0 ) {
3239			printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3240			exit( -1 );
3241		}
3242		if ( my_sb.st_nlink > 2 ) {
3243			printf( "root dir should be emnpty! \n" );
3244			exit( -1 );
3245		}
3246		exit( 0 );
3247	}
3248
3249	/* parent process -
3250	 * wait for child to exit
3251	 */
3252	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3253	if ( my_wait_pid == -1 ) {
3254		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3255		goto test_failed_exit;
3256	}
3257
3258	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3259		printf( "bad exit status\n" );
3260		goto test_failed_exit;
3261	}
3262
3263	my_err = 0;
3264	goto test_passed_exit;
3265
3266test_failed_exit:
3267	my_err = -1;
3268
3269test_passed_exit:
3270	if ( my_pathp != NULL ) {
3271		my_err = rmdir( my_pathp );
3272		if ( my_err != 0 ) {
3273			printf( "rmdir failed with error %d - \"%s\" path %p\n", errno, strerror( errno), my_pathp );
3274		}
3275		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3276	}
3277	return( my_err );
3278}
3279
3280/*  **************************************************************************************************************
3281 *	Test getpgrp, getpgid, getsid, setpgid, setpgrp, setsid system calls.
3282 *  **************************************************************************************************************
3283 */
3284int process_group_test( void * the_argp )
3285{
3286	int		my_err = 0, i = 0;
3287	pid_t		my_session_id, my_pid, my_process_group;
3288
3289	/* get current session ID, pgid, and pid */
3290	my_session_id = getsid( 0 );
3291	if ( my_session_id == -1 ) {
3292		printf( "getsid call failed with error %d - \"%s\" \n",
3293				errno, strerror( errno ) );
3294		goto test_failed_exit;
3295	}
3296
3297	my_pid = getpid( );
3298	my_process_group = getpgrp( );
3299
3300	/* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */
3301	if ( my_process_group != getpgid( 0 ) ) {
3302		printf( "getpgrp and getpgid did not return the same process group ID \n" );
3303		printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group );
3304		goto test_failed_exit;
3305	}
3306
3307	if ( my_pid == my_process_group ) {
3308		/* we are process group leader */
3309		my_err = setsid( );
3310		if ( my_err == 0  || errno != EPERM ) {
3311			printf( "setsid call should have failed with EPERM\n" );
3312			goto test_failed_exit;
3313		}
3314	} else {
3315		/* we are not process group leader: try creating new session */
3316		my_err = setsid( );
3317		if ( my_err == -1 ) {
3318			printf( "setsid call failed with error %d - \"%s\" \n",
3319					errno, strerror( errno ) );
3320			goto test_failed_exit;
3321		}
3322
3323		if ( my_process_group == getpgid( 0 ) ) {
3324			printf( "process group was not reset \n" );
3325			goto test_failed_exit;
3326		}
3327	}
3328
3329	/* find an unused process group ID */
3330	for ( i = 10000; i < 1000000; i++ ) {
3331		my_process_group = getpgid( i );
3332		if ( my_process_group == -1 ) {
3333			break;
3334		}
3335	}
3336
3337	/* this should fail */
3338	my_err = setpgid( 0, my_process_group );
3339	if ( my_err != -1 ) {
3340		printf( "setpgid should have failed, but did not \n" );
3341		goto test_failed_exit;
3342	}
3343
3344	my_err = 0;
3345	goto test_passed_exit;
3346
3347test_failed_exit:
3348	my_err = -1;
3349
3350test_passed_exit:
3351	return( my_err );
3352}
3353
3354/*  **************************************************************************************************************
3355 *	Test fcntl system calls.
3356 *  **************************************************************************************************************
3357 */
3358int fcntl_test( void * the_argp )
3359{
3360	int			my_err, my_result, my_tmep;
3361	int			my_fd = -1;
3362	int			my_newfd = -1;
3363	char *		my_pathp = NULL;
3364	kern_return_t           my_kr;
3365
3366        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3367        if(my_kr != KERN_SUCCESS){
3368                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3369                goto test_failed_exit;
3370        }
3371
3372	*my_pathp = 0x00;
3373	strcat( my_pathp, &g_target_path[0] );
3374	strcat( my_pathp, "/" );
3375
3376	/* create a test file */
3377	my_err = create_random_name( my_pathp, 1 );
3378	if ( my_err != 0 ) {
3379		goto test_failed_exit;
3380	}
3381
3382	/* open our test file and use fcntl to get / set file descriptor flags */
3383	my_fd = open( my_pathp, O_RDONLY, 0 );
3384	if ( my_fd == -1 ) {
3385		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3386		goto test_failed_exit;
3387	}
3388
3389	my_result = fcntl( my_fd, F_GETFD, 0 );
3390	if ( my_result == -1 ) {
3391		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3392		goto test_failed_exit;
3393	}
3394
3395	my_tmep = (my_result & FD_CLOEXEC);
3396	if ( my_tmep ) {
3397		/* FD_CLOEXEC is on, let's turn it off */
3398		my_result = fcntl( my_fd, F_SETFD, 0 );
3399	}
3400	else {
3401		/* FD_CLOEXEC is off, let's turn it on */
3402		my_result = fcntl( my_fd, F_SETFD, 1 );
3403	}
3404	if ( my_result == -1 ) {
3405		printf( "fcntl - F_SETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3406		goto test_failed_exit;
3407	}
3408
3409	/* now check to see if it is set correctly */
3410	my_result = fcntl( my_fd, F_GETFD, 0 );
3411	if ( my_result == -1 ) {
3412		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3413		goto test_failed_exit;
3414	}
3415	if ( my_tmep == (my_result & 0x01) ) {
3416		printf( "fcntl - F_SETFD failed to set FD_CLOEXEC correctly!!! \n" );
3417		goto test_failed_exit;
3418	}
3419
3420	/* dup it to a new fd with FD_CLOEXEC forced on */
3421
3422	my_result = fcntl( my_fd, F_DUPFD_CLOEXEC, 0);
3423	if ( my_result == -1 ) {
3424		printf( "fcntl - F_DUPFD_CLOEXEC - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3425		goto test_failed_exit;
3426	}
3427	my_newfd = my_result;
3428
3429	/* check to see that it too is marked with FD_CLOEXEC */
3430
3431	my_result = fcntl( my_newfd, F_GETFD, 0);
3432	if ( my_result == -1 ) {
3433		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3434		goto test_failed_exit;
3435	}
3436	if ( (my_result & FD_CLOEXEC) == 0 ) {
3437		printf( "fcntl - F_DUPFD_CLOEXEC failed to set FD_CLOEXEC!!! \n" );
3438		goto test_failed_exit;
3439	}
3440
3441	close( my_newfd );
3442	my_newfd = -1;
3443
3444#if !TARGET_OS_EMBEDDED /* This section of the test is specific for the desktop platform, refer <rdar://problem/8850905>*/
3445	/* While we're here, dup it via an open of /dev/fd/<fd> .. */
3446
3447	{
3448		char devfdpath[PATH_MAX];
3449
3450		(void) snprintf( devfdpath, sizeof (devfdpath),
3451			"/dev/fd/%u", my_fd );
3452		my_result = open( devfdpath, O_RDONLY | O_CLOEXEC );
3453	}
3454	if ( my_result == -1 ) {
3455		printf( "open call failed on /dev/fd/%u with error %d - \"%s\" \n", my_fd, errno, strerror( errno) );
3456		goto test_failed_exit;
3457	}
3458	my_newfd = my_result;
3459
3460	/* check to see that it too is marked with FD_CLOEXEC */
3461
3462	my_result = fcntl( my_newfd, F_GETFD, 0);
3463	if ( my_result == -1 ) {
3464		printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3465		goto test_failed_exit;
3466	}
3467	if ( (my_result & FD_CLOEXEC) == 0 ) {
3468		printf( "fcntl - O_CLOEXEC open of /dev/fd/%u failed to set FD_CLOEXEC!!! \n", my_fd );
3469		goto test_failed_exit;
3470	}
3471	close ( my_newfd );
3472	my_newfd = -1;
3473#endif
3474	my_err = 0;
3475	goto test_passed_exit;
3476
3477test_failed_exit:
3478	my_err = -1;
3479
3480test_passed_exit:
3481	if ( my_newfd != -1)
3482		close ( my_newfd );
3483	if ( my_fd != -1 )
3484		close( my_fd );
3485	if ( my_pathp != NULL ) {
3486		remove( my_pathp );
3487		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3488	 }
3489	return( my_err );
3490}
3491
3492/*  **************************************************************************************************************
3493 *	Test getpriority, setpriority system calls.
3494 *  **************************************************************************************************************
3495 */
3496int getpriority_setpriority_test( void * the_argp )
3497{
3498	int			my_err;
3499	int			my_priority;
3500	int			my_new_priority;
3501
3502	/* getpriority returns scheduling priority so -1 is a valid value */
3503	errno = 0;
3504	my_priority = getpriority( PRIO_PROCESS, 0 );
3505	if ( my_priority == -1 && errno != 0 ) {
3506		printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3507		goto test_failed_exit;
3508	}
3509
3510	/* change scheduling priority */
3511	my_new_priority = (my_priority == PRIO_MIN) ? (my_priority + 10) : (PRIO_MIN);
3512	my_err = setpriority( PRIO_PROCESS, 0, my_new_priority );
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	/* verify change */
3519	errno = 0;
3520	my_priority = getpriority( PRIO_PROCESS, 0 );
3521	if ( my_priority == -1 && errno != 0 ) {
3522		printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3523		goto test_failed_exit;
3524	}
3525
3526	if ( my_priority != my_new_priority ) {
3527		printf( "setpriority - failed to set correct scheduling priority \n" );
3528		goto test_failed_exit;
3529	}
3530
3531	/* reset scheduling priority */
3532	my_err = setpriority( PRIO_PROCESS, 0, 0 );
3533	if ( my_err == -1 ) {
3534		printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3535		goto test_failed_exit;
3536	}
3537
3538	my_err = 0;
3539	goto test_passed_exit;
3540
3541test_failed_exit:
3542	my_err = -1;
3543
3544test_passed_exit:
3545	return( my_err );
3546}
3547
3548/*  **************************************************************************************************************
3549 *	Test futimes, gettimeofday, settimeofday, utimes system calls.
3550 *  **************************************************************************************************************
3551 */
3552int time_tests( void * the_argp )
3553{
3554	int					my_err;
3555	int					my_fd = -1;
3556	char *				my_pathp = NULL;
3557	struct timeval		my_orig_time;
3558	struct timeval		my_temp_time;
3559	struct timeval		my_utimes[4];
3560	struct timezone		my_tz;
3561	struct stat			my_sb;
3562	kern_return_t           my_kr;
3563
3564	if ( g_skip_setuid_tests != 0 ) {
3565		printf( "\t skipping this test \n" );
3566		my_err = 0;
3567		goto test_passed_exit;
3568	}
3569
3570        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3571        if(my_kr != KERN_SUCCESS){
3572                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3573                goto test_failed_exit;
3574        }
3575
3576	*my_pathp = 0x00;
3577	strcat( my_pathp, &g_target_path[0] );
3578	strcat( my_pathp, "/" );
3579
3580	/* create a test file */
3581	my_err = create_random_name( my_pathp, 1 );
3582	if ( my_err != 0 ) {
3583		goto test_failed_exit;
3584	}
3585
3586	my_err = gettimeofday( &my_orig_time, &my_tz );
3587	if ( my_err == -1 ) {
3588		printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3589		goto test_failed_exit;
3590	}
3591	//printf( "tv_sec %d tv_usec %ld \n", my_orig_time.tv_sec, my_orig_time.tv_usec );
3592
3593	my_temp_time = my_orig_time;
3594	my_temp_time.tv_sec -= 60;
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	my_err = gettimeofday( &my_temp_time, NULL );
3602	if ( my_err == -1 ) {
3603		printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3604		goto test_failed_exit;
3605	}
3606	//printf( "tv_sec %d tv_usec %ld \n", my_temp_time.tv_sec, my_temp_time.tv_usec );
3607	if ( my_orig_time.tv_sec <= my_temp_time.tv_sec ) {
3608		printf( "settimeofday did not set correct time \n" );
3609		goto test_failed_exit;
3610	}
3611
3612	/* set time back to original value plus 1 second */
3613	my_temp_time = my_orig_time;
3614	my_temp_time.tv_sec += 1;
3615	my_err = settimeofday( &my_temp_time, NULL );
3616	if ( my_err == -1 ) {
3617		printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3618		goto test_failed_exit;
3619	}
3620
3621	/* test utimes and futimes - get current access and mod times then change them */
3622	my_err = stat( my_pathp, &my_sb );
3623	if ( my_err != 0 ) {
3624		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3625		goto test_failed_exit;
3626	}
3627	TIMESPEC_TO_TIMEVAL( &my_utimes[0], &my_sb.st_atimespec );
3628	TIMESPEC_TO_TIMEVAL( &my_utimes[1], &my_sb.st_mtimespec );
3629	my_utimes[0].tv_sec -= 120;		/* make access time 2 minutes older */
3630	my_utimes[1].tv_sec -= 120;		/* make mod time 2 minutes older */
3631
3632	my_err = utimes( my_pathp, &my_utimes[0] );
3633	if ( my_err == -1 ) {
3634		printf( "utimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3635		goto test_failed_exit;
3636	}
3637
3638	/* make sure the correct times are set */
3639	my_err = stat( my_pathp, &my_sb );
3640	if ( my_err != 0 ) {
3641		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3642		goto test_failed_exit;
3643	}
3644	TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3645	TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3646	if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3647		 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3648		printf( "utimes failed to set access and mod times \n" );
3649		goto test_failed_exit;
3650	}
3651
3652	my_fd = open( my_pathp, O_RDWR, 0 );
3653	if ( my_fd == -1 ) {
3654		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3655		goto test_failed_exit;
3656	}
3657
3658	my_utimes[0].tv_sec -= 120;  /* make access time 2 minutes older */
3659	my_utimes[1].tv_sec -= 120;  /* make mod time 2 minutes older */
3660	my_err = futimes( my_fd, &my_utimes[0] );
3661	if ( my_err == -1 ) {
3662		printf( "futimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3663		goto test_failed_exit;
3664	}
3665
3666	/* make sure the correct times are set */
3667	my_err = stat( my_pathp, &my_sb );
3668	if ( my_err != 0 ) {
3669		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3670		goto test_failed_exit;
3671	}
3672	TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3673	TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3674	if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3675		 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3676		printf( "futimes failed to set access and mod times \n" );
3677		goto test_failed_exit;
3678	}
3679
3680	my_err = 0;
3681	goto test_passed_exit;
3682
3683test_failed_exit:
3684	my_err = -1;
3685
3686test_passed_exit:
3687	if ( my_fd != -1 )
3688		close( my_fd );
3689	if ( my_pathp != NULL ) {
3690		remove( my_pathp );
3691		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3692	 }
3693	return( my_err );
3694}
3695
3696/*  **************************************************************************************************************
3697 *	Test rename, stat system calls.
3698 *  **************************************************************************************************************
3699 */
3700int rename_test( void * the_argp )
3701{
3702	int				my_err;
3703	char *			my_pathp = NULL;
3704	char *			my_new_pathp = NULL;
3705	ino_t			my_file_id;
3706	struct stat		my_sb;
3707	kern_return_t           my_kr;
3708
3709        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3710        if(my_kr != KERN_SUCCESS){
3711                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3712                goto test_failed_exit;
3713        }
3714
3715	*my_pathp = 0x00;
3716	strcat( my_pathp, &g_target_path[0] );
3717	strcat( my_pathp, "/" );
3718
3719	/* create a test file */
3720	my_err = create_random_name( my_pathp, 1 );
3721	if ( my_err != 0 ) {
3722		goto test_failed_exit;
3723	}
3724
3725        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3726        if(my_kr != KERN_SUCCESS){
3727                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3728                goto test_failed_exit;
3729        }
3730
3731	*my_new_pathp = 0x00;
3732	strcat( my_new_pathp, &g_target_path[0] );
3733	strcat( my_new_pathp, "/" );
3734
3735	/* get a unique name for our rename test */
3736	my_err = create_random_name( my_new_pathp, 0 );
3737	if ( my_err != 0 ) {
3738		goto test_failed_exit;
3739	}
3740
3741	/* save file ID for later use */
3742	my_err = stat( my_pathp, &my_sb );
3743	if ( my_err != 0 ) {
3744		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3745		goto test_failed_exit;
3746	}
3747	my_file_id = my_sb.st_ino;
3748
3749	/* test rename */
3750	my_err = rename( my_pathp, my_new_pathp );
3751	if ( my_err == -1 ) {
3752		printf( "rename - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3753		goto test_failed_exit;
3754	}
3755
3756	/* make sure old name is no longer there */
3757	my_err = stat( my_pathp, &my_sb );
3758	if ( my_err == 0 ) {
3759		printf( "rename call failed - found old name \n" );
3760		goto test_failed_exit;
3761	}
3762
3763	/* make sure new name is there and is correct file id */
3764	my_err = stat( my_new_pathp, &my_sb );
3765	if ( my_err != 0 ) {
3766		printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3767		goto test_failed_exit;
3768	}
3769	if ( my_file_id != my_sb.st_ino ) {
3770		printf( "rename failed - wrong file id \n" );
3771		goto test_failed_exit;
3772	}
3773
3774	my_err = 0;
3775	goto test_passed_exit;
3776
3777test_failed_exit:
3778	my_err = -1;
3779
3780test_passed_exit:
3781	if ( my_pathp != NULL ) {
3782		remove( my_pathp );
3783		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3784	 }
3785	if ( my_new_pathp != NULL ) {
3786		remove( my_new_pathp );
3787		vm_deallocate(mach_task_self(), (vm_address_t)my_new_pathp, PATH_MAX);
3788	 }
3789	return( my_err );
3790}
3791
3792/*  **************************************************************************************************************
3793 *	Test locking system calls.
3794 *  **************************************************************************************************************
3795 */
3796int locking_test( void * the_argp )
3797{
3798	int			my_err, my_status;
3799	pid_t		my_pid, my_wait_pid;
3800	int			my_fd = -1;
3801	char *		my_pathp = NULL;
3802	kern_return_t           my_kr;
3803
3804        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3805        if(my_kr != KERN_SUCCESS){
3806                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3807                goto test_failed_exit;
3808        }
3809
3810	*my_pathp = 0x00;
3811	strcat( my_pathp, &g_target_path[0] );
3812	strcat( my_pathp, "/" );
3813
3814	/* create a test file */
3815	my_err = create_random_name( my_pathp, 1 );
3816	if ( my_err != 0 ) {
3817		goto test_failed_exit;
3818	}
3819
3820	/* test flock */
3821	my_fd = open( my_pathp, O_RDWR, 0 );
3822	if ( my_fd == -1 ) {
3823		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3824		goto test_failed_exit;
3825	}
3826
3827	my_err =  flock( my_fd, LOCK_EX );
3828	if ( my_err == -1 ) {
3829		printf( "flock - LOCK_EX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3830		goto test_failed_exit;
3831	}
3832
3833	/*
3834	 * spin off a child process that we will use for testing.
3835	 */
3836	my_pid = fork( );
3837	if ( my_pid == -1 ) {
3838		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3839		goto test_failed_exit;
3840	}
3841	if ( my_pid == 0 ) {
3842		/*
3843		 * child process.
3844		 */
3845		int			my_child_fd = -1;
3846		int			my_child_err;
3847
3848		my_child_fd = open( my_pathp, O_RDWR, 0 );
3849		if ( my_child_fd == -1 ) {
3850			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3851			my_child_err = -1;
3852			goto child_exit;
3853		}
3854
3855		my_err =  flock( my_child_fd, (LOCK_EX | LOCK_NB) );
3856		if ( my_err == -1 ) {
3857			if ( errno != EWOULDBLOCK ) {
3858				printf( "flock call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3859				my_child_err = -1;
3860				goto child_exit;
3861			}
3862		}
3863		else {
3864			printf( "flock call should have failed with EWOULDBLOCK err \n" );
3865			my_child_err = -1;
3866			goto child_exit;
3867		}
3868		my_child_err = 0;
3869child_exit:
3870		if ( my_child_fd != -1 )
3871			close( my_child_fd );
3872		exit( my_child_err );
3873	}
3874
3875	/* parent process -
3876	 * wait for child to exit
3877	 */
3878	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3879	if ( my_wait_pid == -1 ) {
3880		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3881		goto test_failed_exit;
3882	}
3883
3884	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3885		goto test_failed_exit;
3886	}
3887
3888	my_err =  flock( my_fd, LOCK_UN );
3889	if ( my_err == -1 ) {
3890		printf( "flock - LOCK_UN - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3891		goto test_failed_exit;
3892	}
3893
3894	my_err = 0;
3895	goto test_passed_exit;
3896
3897test_failed_exit:
3898	my_err = -1;
3899
3900test_passed_exit:
3901	if ( my_fd != -1 )
3902		close( my_fd );
3903	if ( my_pathp != NULL ) {
3904		remove( my_pathp );
3905		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3906	 }
3907	return( my_err );
3908}
3909
3910/*  **************************************************************************************************************
3911 *	Test mkfifo system calls.
3912 *  **************************************************************************************************************
3913 */
3914int mkfifo_test( void * the_argp )
3915{
3916	int			my_err, my_status;
3917	pid_t		my_pid, my_wait_pid;
3918	int			my_fd = -1;
3919	char *		my_pathp = NULL;
3920	ssize_t		my_result;
3921	off_t		my_current_offset;
3922	kern_return_t           my_kr;
3923
3924        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3925        if(my_kr != KERN_SUCCESS){
3926                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3927                goto test_failed_exit;
3928        }
3929
3930	*my_pathp = 0x00;
3931	strcat( my_pathp, &g_target_path[0] );
3932	strcat( my_pathp, "/" );
3933
3934	/* get unique name for our fifo */
3935	my_err = create_random_name( my_pathp, 0 );
3936	if ( my_err != 0 ) {
3937		goto test_failed_exit;
3938	}
3939
3940	my_err = mkfifo( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
3941	if ( my_err != 0 ) {
3942		printf( "mkfifo failed with errno %d - %s. \n", errno, strerror( errno ) );
3943		goto test_failed_exit;
3944	}
3945
3946	/*
3947	 * spin off a child process that we will use for testing.
3948	 */
3949	my_pid = fork( );
3950	if ( my_pid == -1 ) {
3951		printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3952		goto test_failed_exit;
3953	}
3954	if ( my_pid == 0 ) {
3955		/*
3956		 * child process.
3957		 */
3958		int			my_child_fd = -1;
3959		int			my_child_err;
3960		char		my_buffer[64];
3961
3962		/* open read end of fifo */
3963		my_child_fd = open( my_pathp, O_RDWR, 0 );
3964		if ( my_child_fd == -1 ) {
3965			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3966			my_child_err = -1;
3967			goto child_exit;
3968		}
3969
3970		/* read message from parent */
3971		bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
3972		my_result = read( my_child_fd, &my_buffer[0], sizeof(my_buffer) );
3973		if ( my_result == -1 ) {
3974			printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3975			my_child_err = -1;
3976			goto child_exit;
3977		}
3978		if ( strcmp( "parent to child", &my_buffer[0] ) != 0 ) {
3979			printf( "read wrong message from parent \n" );
3980			my_child_err = -1;
3981			goto child_exit;
3982		}
3983
3984		my_child_err = 0;
3985child_exit:
3986		if ( my_child_fd != -1 )
3987			close( my_child_fd );
3988		exit( my_child_err );
3989	}
3990
3991	/* parent process - open write end of fifo
3992	 */
3993	my_fd = open( my_pathp, O_WRONLY, 0 );
3994	if ( my_fd == -1 ) {
3995		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3996		goto test_failed_exit;
3997	}
3998
3999	/* make sure we can't seek on a fifo */
4000	my_current_offset = lseek( my_fd, 0, SEEK_CUR );
4001	if ( my_current_offset != -1 ) {
4002		printf( "lseek on fifo should fail but did not \n" );
4003		goto test_failed_exit;
4004	}
4005
4006	my_result = write( my_fd, "parent to child", 15 );
4007	if ( my_result == -1 ) {
4008		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4009		goto test_failed_exit;
4010	}
4011
4012	my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
4013	if ( my_wait_pid == -1 ) {
4014		printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
4015		goto test_failed_exit;
4016	}
4017
4018	if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
4019		goto test_failed_exit;
4020	}
4021
4022	my_err = 0;
4023	goto test_passed_exit;
4024
4025test_failed_exit:
4026	my_err = -1;
4027
4028test_passed_exit:
4029	if ( my_fd != -1 )
4030		close( my_fd );
4031	if ( my_pathp != NULL ) {
4032		remove( my_pathp );
4033		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4034	 }
4035	return( my_err );
4036}
4037
4038/*  **************************************************************************************************************
4039 *	Test quotactl system calls.
4040 *  **************************************************************************************************************
4041 */
4042int quotactl_test( void * the_argp )
4043{
4044#if !TARGET_OS_EMBEDDED
4045	int				my_err;
4046	int				is_quotas_on = 0;
4047	struct dqblk	my_quota_blk;
4048
4049	if ( g_skip_setuid_tests != 0 ) {
4050		printf( "\t skipping this test \n" );
4051		my_err = 0;
4052		goto test_passed_exit;
4053	}
4054
4055	/* start off by checking the status of quotas on the boot volume */
4056	my_err = quotactl( "/mach_kernel", QCMD(Q_QUOTASTAT, USRQUOTA), 0, (caddr_t)&is_quotas_on );
4057	if ( my_err == -1 ) {
4058		printf( "quotactl - Q_QUOTASTAT - failed with errno %d - %s \n", errno, strerror( errno ) );
4059		goto test_failed_exit;
4060	}
4061
4062	if ( is_quotas_on == 0 ) {
4063		/* quotas are off */
4064		my_err = 0;
4065		goto test_passed_exit;
4066	}
4067
4068	my_err = quotactl( "/mach_kernel", QCMD(Q_GETQUOTA, USRQUOTA), getuid(), (caddr_t)&my_quota_blk );
4069	if ( my_err == -1 ) {
4070		printf( "quotactl - Q_GETQUOTA - failed with errno %d - %s \n", errno, strerror( errno ) );
4071		goto test_failed_exit;
4072	}
4073
4074	my_err = 0;
4075	goto test_passed_exit;
4076
4077test_failed_exit:
4078	my_err = -1;
4079
4080test_passed_exit:
4081	return( my_err );
4082#else
4083	printf( "\t--> Not supported on EMBEDDED TARGET\n" );
4084	return 0;
4085#endif
4086}
4087
4088/*  **************************************************************************************************************
4089 *	Test getrlimit, setrlimit system calls.
4090 *  **************************************************************************************************************
4091 */
4092int limit_tests( void * the_argp )
4093{
4094	int				my_err;
4095	struct rlimit	my_current_rlimit;
4096	struct rlimit	my_rlimit;
4097
4098 	my_err = getrlimit( RLIMIT_NOFILE, &my_current_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_current_rlimit.rlim_cur != RLIM_INFINITY ) {
4104		if ( my_current_rlimit.rlim_cur != my_current_rlimit.rlim_max )
4105			my_current_rlimit.rlim_cur += 1;
4106		else
4107			my_current_rlimit.rlim_cur -= 1;
4108		my_rlimit.rlim_cur = my_current_rlimit.rlim_cur;
4109		my_rlimit.rlim_max = my_current_rlimit.rlim_max;
4110		my_err = setrlimit( RLIMIT_NOFILE, &my_rlimit );
4111		if ( my_err == -1 ) {
4112			printf( "setrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4113			goto test_failed_exit;
4114		}
4115
4116		/* verify that we set a new limit */
4117		bzero( (void *) &my_rlimit, sizeof( my_rlimit ) );
4118		my_err = getrlimit( RLIMIT_NOFILE, &my_rlimit );
4119		if ( my_err == -1 ) {
4120			printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4121			goto test_failed_exit;
4122		}
4123		if ( my_rlimit.rlim_cur != my_current_rlimit.rlim_cur ) {
4124			printf( "failed to get/set new RLIMIT_NOFILE soft limit \n" );
4125			printf( "soft limits - current %lld should be %lld \n", my_rlimit.rlim_cur, my_current_rlimit.rlim_cur );
4126			goto test_failed_exit;
4127		}
4128
4129#if CONFORMANCE_CHANGES_IN_XNU // can't do this check until conformance changes get into xnu
4130		printf( "hard limits - current %lld should be %lld \n", my_rlimit.rlim_max, my_current_rlimit.rlim_max );
4131		if ( my_rlimit.rlim_max != my_current_rlimit.rlim_max ) {
4132			printf( "failed to get/set new RLIMIT_NOFILE hard limit \n" );
4133			goto test_failed_exit;
4134		}
4135#endif
4136
4137		/*
4138		 * A test for a limit that won't fit in a signed 32 bits, a la 5414697
4139		 * Note: my_rlimit should still have a valid rlim_max.
4140		 */
4141		long long biglim = 2147483649ll;	/* Just over 2^31 */
4142		my_rlimit.rlim_cur = biglim;
4143		my_err = setrlimit(RLIMIT_CPU, &my_rlimit);
4144		if (my_err == -1) {
4145			printf("failed to set large limit.\n");
4146			goto test_failed_exit;
4147		}
4148
4149		bzero(&my_rlimit, sizeof(struct rlimit));
4150		my_err = getrlimit(RLIMIT_CPU, &my_rlimit);
4151		if (my_err == -1) {
4152			printf("after setting large value, failed to getrlimit().\n");
4153			goto test_failed_exit;
4154		}
4155
4156		if (my_rlimit.rlim_cur != biglim) {
4157			printf("didn't retrieve large limit.\n");
4158			goto test_failed_exit;
4159		}
4160	}
4161
4162	my_err = 0;
4163	goto test_passed_exit;
4164
4165test_failed_exit:
4166	my_err = -1;
4167
4168test_passed_exit:
4169	return( my_err );
4170}
4171
4172/*  **************************************************************************************************************
4173 *	Test getattrlist, getdirentriesattr, setattrlist system calls.
4174 *  **************************************************************************************************************
4175 */
4176struct test_attr_buf {
4177	uint32_t			length;
4178	fsobj_type_t		obj_type;
4179	fsobj_id_t			obj_id;
4180	struct timespec   	backup_time;
4181};
4182
4183typedef struct test_attr_buf test_attr_buf;
4184
4185int directory_tests( void * the_argp )
4186{
4187	int					my_err, done, found_it, i;
4188	int					my_fd = -1;
4189	int					is_ufs = 0;
4190	char *				my_pathp = NULL;
4191	char *				my_bufp = NULL;
4192	char *				my_file_namep;
4193#ifdef __LP64__
4194	unsigned int		my_base;
4195	unsigned int		my_count;
4196	unsigned int		my_new_state;
4197#else
4198	unsigned long		my_base;
4199	unsigned long		my_count;
4200	unsigned long		my_new_state;
4201#endif
4202	fsobj_id_t			my_obj_id;
4203	struct timespec		my_new_backup_time;
4204	struct attrlist		my_attrlist;
4205	test_attr_buf		my_attr_buf[4];
4206	struct statfs 		my_statfs_buf;
4207	kern_return_t           my_kr;
4208
4209	/* need to know type of file system */
4210	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4211	if ( my_err == -1 ) {
4212		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4213		goto test_failed_exit;
4214	}
4215	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4216		is_ufs = 1;
4217	}
4218
4219        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE);
4220        if(my_kr != KERN_SUCCESS){
4221                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4222                goto test_failed_exit;
4223        }
4224
4225        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4226        if(my_kr != KERN_SUCCESS){
4227                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4228                goto test_failed_exit;
4229        }
4230
4231	*my_pathp = 0x00;
4232	strcat( my_pathp, &g_target_path[0] );
4233	strcat( my_pathp, "/" );
4234
4235	/* create a test file */
4236	my_err = create_random_name( my_pathp, 1 );
4237	if ( my_err != 0 ) {
4238		goto test_failed_exit;
4239	}
4240
4241	/* get pointer to just the file name */
4242	my_file_namep = strrchr( my_pathp, '/' );
4243	my_file_namep++;
4244
4245	/* check out the  test directory */
4246	my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4247	if ( my_fd == -1 ) {
4248		printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4249		goto test_failed_exit;
4250	}
4251
4252	/* test get/setattrlist */
4253	memset( &my_attrlist, 0, sizeof(my_attrlist) );
4254	my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4255	my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4256	my_err = getattrlist( my_pathp, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf[0]), 0 );
4257
4258	if ( my_err != 0 ) {
4259		if ( errno == ENOTSUP && is_ufs ) {
4260			/* getattr calls not supported on ufs */
4261			my_err = 0;
4262			goto test_passed_exit;
4263		}
4264		printf( "getattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4265		goto test_failed_exit;
4266	}
4267	/* validate returned data */
4268	if ( my_attr_buf[0].obj_type != VREG ) {
4269		printf( "getattrlist returned incorrect obj_type data. \n" );
4270		goto test_failed_exit;
4271	}
4272
4273	/* set new backup time */
4274	my_obj_id = my_attr_buf[0].obj_id;
4275	my_new_backup_time = my_attr_buf[0].backup_time;
4276	my_new_backup_time.tv_sec += 60;
4277	my_attr_buf[0].backup_time.tv_sec = my_new_backup_time.tv_sec;
4278	my_attrlist.commonattr = (ATTR_CMN_BKUPTIME);
4279	my_err = setattrlist( my_pathp, &my_attrlist, &my_attr_buf[0].backup_time, sizeof(my_attr_buf[0].backup_time), 0 );
4280	if ( my_err != 0 ) {
4281		printf( "setattrlist call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4282		goto test_failed_exit;
4283	}
4284
4285	/* validate setattrlist using getdirentriesattr */
4286	close( my_fd );
4287	my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4288	if ( my_fd == -1 ) {
4289		printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4290		goto test_failed_exit;
4291	}
4292	memset( &my_attrlist, 0, sizeof(my_attrlist) );
4293	memset( &my_attr_buf, 0, sizeof(my_attr_buf) );
4294	my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4295	my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4296	my_count = 4;
4297	my_base = 0;
4298	my_err = getdirentriesattr( my_fd, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf), &my_count,
4299								&my_base, &my_new_state, 0 );
4300	if ( my_err < 0 ) {
4301		printf( "getdirentriesattr call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4302		goto test_failed_exit;
4303	}
4304
4305	found_it = 0;
4306	for ( i = 0; i < my_count; i++ ) {
4307		if ( my_attr_buf[i].obj_id.fid_objno == my_obj_id.fid_objno &&
4308			 my_attr_buf[i].obj_id.fid_generation == my_obj_id.fid_generation ) {
4309			found_it = 1;
4310			if ( my_attr_buf[i].backup_time.tv_sec !=  my_new_backup_time.tv_sec ) {
4311				printf( "setattrlist failed to set backup time. \n" );
4312				goto test_failed_exit;
4313			}
4314		}
4315	}
4316	if ( found_it == 0 ) {
4317		printf( "getdirentriesattr failed to find test file. \n" );
4318		goto test_failed_exit;
4319	}
4320
4321	my_err = 0;
4322	goto test_passed_exit;
4323
4324test_failed_exit:
4325	if(my_err != 0)
4326		my_err = -1;
4327
4328test_passed_exit:
4329	if ( my_fd != -1 )
4330		close( my_fd );
4331	if ( my_pathp != NULL ) {
4332		remove( my_pathp );
4333		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4334	 }
4335	if ( my_bufp != NULL ) {
4336		vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5));
4337	 }
4338	return( my_err );
4339}
4340
4341/*  **************************************************************************************************************
4342 *	Test exchangedata system calls.
4343 *  **************************************************************************************************************
4344 */
4345int exchangedata_test( void * the_argp )
4346{
4347	int				my_err;
4348	int				my_fd1 = -1;
4349	int				my_fd2 = -1;
4350	char *			my_file1_pathp = NULL;
4351	char *			my_file2_pathp = NULL;
4352	ssize_t			my_result;
4353	char			my_buffer[16];
4354	struct statfs	my_statfs_buf;
4355	kern_return_t           my_kr;
4356
4357	/* need to know type of file system */
4358	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4359	if ( my_err == -1 ) {
4360		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4361		goto test_failed_exit;
4362	}
4363	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4364		/* ufs does not support exchangedata */
4365		my_err = 0;
4366		goto test_passed_exit;
4367	}
4368
4369        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file1_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4370        if(my_kr != KERN_SUCCESS){
4371                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4372                goto test_failed_exit;
4373        }
4374
4375	*my_file1_pathp = 0x00;
4376	strcat( my_file1_pathp, &g_target_path[0] );
4377	strcat( my_file1_pathp, "/" );
4378
4379	/* create a test file */
4380	my_err = create_random_name( my_file1_pathp, 1 );
4381	if ( my_err != 0 ) {
4382		printf( "create_random_name my_err: %d\n", my_err );
4383		goto test_failed_exit;
4384	}
4385	my_fd1 = open( my_file1_pathp, O_RDWR, 0 );
4386	if ( my_fd1 == -1 ) {
4387		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4388		goto test_failed_exit;
4389	}
4390	my_result = write( my_fd1, "11111111", 8 );
4391	if ( my_result == -1 ) {
4392		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4393		goto test_failed_exit;
4394	}
4395
4396        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file2_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4397        if(my_kr != KERN_SUCCESS){
4398                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4399                goto test_failed_exit;
4400        }
4401
4402	*my_file2_pathp = 0x00;
4403	strcat( my_file2_pathp, &g_target_path[0] );
4404	strcat( my_file2_pathp, "/" );
4405
4406	/* create a test file */
4407	my_err = create_random_name( my_file2_pathp, 1 );
4408	if ( my_err != 0 ) {
4409		printf( "create_random_name my_err: %d\n", my_err );
4410		goto test_failed_exit;
4411	}
4412	my_fd2 = open( my_file2_pathp, O_RDWR, 0 );
4413	if ( my_fd2 == -1 ) {
4414		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4415		goto test_failed_exit;
4416	}
4417	my_result = write( my_fd2, "22222222", 8 );
4418	if ( my_result == -1 ) {
4419		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4420		goto test_failed_exit;
4421	}
4422	close(my_fd1);
4423	my_fd1 = -1;
4424	close(my_fd2);
4425	my_fd2 = -1;
4426
4427	/* test exchangedata */
4428	my_err = exchangedata( my_file1_pathp, my_file2_pathp, 0 );
4429	if ( my_err == -1 ) {
4430		printf( "exchangedata failed with error %d - \"%s\" \n", errno, strerror( errno) );
4431		goto test_failed_exit;
4432	}
4433
4434	/* now validate exchange */
4435	my_fd1 = open( my_file1_pathp, O_RDONLY, 0 );
4436	if ( my_fd1 == -1 ) {
4437		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4438		goto test_failed_exit;
4439	}
4440	bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
4441	my_result = read( my_fd1, &my_buffer[0], 8 );
4442	if ( my_result == -1 ) {
4443		printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4444		goto test_failed_exit;
4445	}
4446
4447	if ( memcmp( &my_buffer[0], "22222222", 8 ) != 0 ) {
4448		printf( "exchangedata failed - incorrect data in file \n" );
4449		goto test_failed_exit;
4450	}
4451
4452	my_err = 0;
4453	goto test_passed_exit;
4454
4455test_failed_exit:
4456	my_err = -1;
4457
4458test_passed_exit:
4459	if ( my_fd1 != -1 )
4460		close( my_fd1 );
4461	if ( my_file1_pathp != NULL ) {
4462		remove( my_file1_pathp );
4463		vm_deallocate(mach_task_self(), (vm_address_t)my_file1_pathp, PATH_MAX);
4464	 }
4465	if ( my_fd2 != -1 )
4466		close( my_fd2 );
4467	if ( my_file2_pathp != NULL ) {
4468		remove( my_file2_pathp );
4469		vm_deallocate(mach_task_self(), (vm_address_t)my_file2_pathp, PATH_MAX);
4470	 }
4471	return( my_err );
4472}
4473
4474
4475/*  **************************************************************************************************************
4476 *	Test searchfs system calls.
4477 *  **************************************************************************************************************
4478 */
4479
4480struct packed_name_attr {
4481    u_int32_t	            size;	/* Of the remaining fields */
4482    struct attrreference	ref;	/* Offset/length of name itself */
4483    char 			        name[  PATH_MAX ];
4484};
4485
4486struct packed_attr_ref {
4487    u_int32_t    		    size;	/* Of the remaining fields */
4488    struct attrreference	ref;	/* Offset/length of attr itself */
4489};
4490
4491struct packed_result {
4492    u_int32_t	        size;		/* Including size field itself */
4493    attrreference_t     obj_name;
4494    struct fsobj_id	    obj_id;
4495    struct timespec     obj_create_time;
4496    char                room_for_name[ 64 ];
4497};
4498typedef struct packed_result packed_result;
4499typedef struct packed_result * packed_result_p;
4500
4501#define MAX_MATCHES	10
4502#define MAX_EBUSY_RETRIES 5
4503
4504int searchfs_test( void * the_argp )
4505{
4506#if !TARGET_OS_EMBEDDED
4507	int						my_err, my_items_found = 0, my_ebusy_count;
4508	char *					my_pathp = NULL;
4509    unsigned long			my_matches;
4510    unsigned long			my_search_options;
4511    struct fssearchblock	my_search_blk;
4512    struct attrlist			my_return_list;
4513    struct searchstate		my_search_state;
4514    struct packed_name_attr	my_info1;
4515    struct packed_attr_ref	my_info2;
4516    packed_result			my_result_buffer[ MAX_MATCHES ];
4517	struct statfs			my_statfs_buf;
4518	kern_return_t           my_kr;
4519
4520	/* need to know type of file system */
4521	my_err = statfs( &g_target_path[0], &my_statfs_buf );
4522	if ( my_err == -1 ) {
4523		printf( "statfs call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
4524		goto test_failed_exit;
4525	}
4526	if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4527		/* ufs does not support exchangedata */
4528		my_err = 0;
4529		goto test_passed_exit;
4530	}
4531
4532        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4533        if(my_kr != KERN_SUCCESS){
4534                printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4535                goto test_failed_exit;
4536        }
4537
4538	*my_pathp = 0x00;
4539	strcat( my_pathp, &g_target_path[0] );
4540	strcat( my_pathp, "/" );
4541
4542	/* create test files */
4543	my_err = create_file_with_name( my_pathp, "foo", 0 );
4544	if ( my_err < 0 ) {
4545		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4546		goto test_failed_exit;
4547	}
4548
4549	my_err = create_file_with_name( my_pathp, "foobar", 0 );
4550	if ( my_err < 0 ) {
4551		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4552		goto test_failed_exit;
4553	}
4554
4555	my_err = create_file_with_name( my_pathp, "foofoo", 0 );
4556	if ( my_err < 0 ) {
4557		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4558		goto test_failed_exit;
4559	}
4560
4561	my_err = create_file_with_name( my_pathp, "xxxfoo", 0 );
4562	if ( my_err < 0 ) {
4563		printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4564		goto test_failed_exit;
4565	}
4566
4567    /* EBUSY count  updated below the catalogue_changed label */
4568    my_ebusy_count = 0;
4569
4570catalogue_changed:
4571	/* search target volume for all file system objects with "foo" in the name */
4572    /* Set up the attributes we're searching on. */
4573    my_items_found = 0; /* Set this here in case we're completely restarting */
4574    my_search_blk.searchattrs.bitmapcount = ATTR_BIT_MAP_COUNT;
4575    my_search_blk.searchattrs.reserved = 0;
4576    my_search_blk.searchattrs.commonattr = ATTR_CMN_NAME;
4577    my_search_blk.searchattrs.volattr = 0;
4578    my_search_blk.searchattrs.dirattr = 0;
4579    my_search_blk.searchattrs.fileattr = 0;
4580    my_search_blk.searchattrs.forkattr = 0;
4581
4582    /* Set up the attributes we want for all returned matches. */
4583    /* Why is returnattrs a pointer instead of an embedded struct? */
4584    my_search_blk.returnattrs = &my_return_list;
4585    my_return_list.bitmapcount = ATTR_BIT_MAP_COUNT;
4586    my_return_list.reserved = 0;
4587    my_return_list.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJID | ATTR_CMN_CRTIME;
4588    my_return_list.volattr = 0;
4589    my_return_list.dirattr = 0;
4590    my_return_list.fileattr = 0;
4591    my_return_list.forkattr = 0;
4592
4593    /* Allocate a buffer for returned matches */
4594    my_search_blk.returnbuffer = my_result_buffer;
4595    my_search_blk.returnbuffersize = sizeof(my_result_buffer);
4596
4597    /* Pack the searchparams1 into a buffer */
4598    /* NOTE: A name appears only in searchparams1 */
4599    strcpy( my_info1.name, "foo" );
4600    my_info1.ref.attr_dataoffset = sizeof(struct attrreference);
4601    my_info1.ref.attr_length = strlen(my_info1.name) + 1;
4602    my_info1.size = sizeof(struct attrreference) + my_info1.ref.attr_length;
4603    my_search_blk.searchparams1 = &my_info1;
4604    my_search_blk.sizeofsearchparams1 = my_info1.size + sizeof(u_int32_t);
4605
4606    /* Pack the searchparams2 into a buffer */
4607    my_info2.size = sizeof(struct attrreference);
4608    my_info2.ref.attr_dataoffset = sizeof(struct attrreference);
4609    my_info2.ref.attr_length = 0;
4610    my_search_blk.searchparams2 = &my_info2;
4611    my_search_blk.sizeofsearchparams2 = sizeof(my_info2);
4612
4613    /* Maximum number of matches we want */
4614    my_search_blk.maxmatches = MAX_MATCHES;
4615
4616    /* Maximum time to search, per call */
4617    my_search_blk.timelimit.tv_sec = 1;
4618    my_search_blk.timelimit.tv_usec = 0;
4619
4620    my_search_options = (SRCHFS_START | SRCHFS_MATCHPARTIALNAMES |
4621						 SRCHFS_MATCHFILES | SRCHFS_MATCHDIRS);
4622	do {
4623		char *  my_end_ptr;
4624		char *	my_ptr;
4625		int		i;
4626
4627		my_err = searchfs( my_pathp, &my_search_blk, &my_matches, 0, my_search_options, &my_search_state );
4628        if ( my_err == -1 )
4629            my_err = errno;
4630        if ( (my_err == 0 || my_err == EAGAIN) && my_matches > 0 ) {
4631            /* Unpack the results */
4632          //  printf("my_matches %d \n", my_matches);
4633            my_ptr = (char *) &my_result_buffer[0];
4634            my_end_ptr = (my_ptr + sizeof(my_result_buffer));
4635            for ( i = 0; i < my_matches; ++i ) {
4636                packed_result_p		my_result_p = (packed_result_p) my_ptr;
4637				char *				my_name_p;
4638
4639				/* see if we foound all our test files */
4640				my_name_p = (((char *)(&my_result_p->obj_name)) + my_result_p->obj_name.attr_dataoffset);
4641				if ( memcmp( my_name_p, "foo", 3 ) == 0 ||
4642					 memcmp( my_name_p, "foobar", 6 ) == 0 ||
4643					 memcmp( my_name_p, "foofoo", 6 ) == 0 ||
4644					 memcmp( my_name_p, "xxxfoo", 6 ) == 0 ) {
4645					my_items_found++;
4646				}
4647#if DEBUG
4648                printf("obj_name \"%.*s\" \n",
4649                    (int) my_result_p->obj_name.attr_length,
4650                    (((char *)(&my_result_p->obj_name)) +
4651                     my_result_p->obj_name.attr_dataoffset));
4652                printf("size %d fid_objno %d fid_generation %d tv_sec 0x%02LX \n",
4653                    my_result_p->size, my_result_p->obj_id.fid_objno,
4654                    my_result_p->obj_id.fid_generation,
4655                    my_result_p->obj_create_time.tv_sec);
4656#endif
4657                my_ptr = (my_ptr + my_result_p->size);
4658                if (my_ptr > my_end_ptr)
4659                    break;
4660            }
4661        }
4662
4663	/* EBUSY indicates catalogue change; retry a few times. */
4664	if ((my_err == EBUSY) && (my_ebusy_count++ < MAX_EBUSY_RETRIES)) {
4665		goto catalogue_changed;
4666	}
4667	if ( !(my_err == 0 || my_err == EAGAIN) ) {
4668		printf( "searchfs failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4669	}
4670	my_search_options &= ~SRCHFS_START;
4671    } while ( my_err == EAGAIN );
4672
4673	if ( my_items_found < 4 ) {
4674		printf( "searchfs failed to find all test files \n" );
4675		goto test_failed_exit;
4676	}
4677
4678	my_err = 0;
4679	goto test_passed_exit;
4680
4681test_failed_exit:
4682	my_err = -1;
4683
4684test_passed_exit:
4685	if ( my_pathp != NULL ) {
4686		char *   my_ptr = (my_pathp + strlen( my_pathp ));
4687		strcat( my_pathp, "foo" );
4688		remove( my_pathp );
4689		*my_ptr = 0x00;
4690		strcat( my_pathp, "foobar" );
4691		remove( my_pathp );
4692		*my_ptr = 0x00;
4693		strcat( my_pathp, "foofoo" );
4694		remove( my_pathp );
4695		*my_ptr = 0x00;
4696		strcat( my_pathp, "xxxfoo" );
4697		remove( my_pathp );
4698		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4699	 }
4700	return( my_err );
4701#else
4702	printf( "\t--> Not supported on EMBEDDED TARGET\n" );
4703	return 0;
4704#endif
4705}
4706
4707
4708#define  AIO_TESTS_BUFFER_SIZE  (1024 * 4000)
4709#define  AIO_TESTS_OUR_COUNT  5
4710/*  **************************************************************************************************************
4711 *	Test aio_error, aio_read, aio_return, aio_suspend, aio_write, fcntl system calls.
4712 *  **************************************************************************************************************
4713 */
4714int aio_tests( void * the_argp )
4715{
4716	int					my_err, i;
4717	char *				my_pathp;
4718	struct aiocb *		my_aiocbp;
4719	ssize_t				my_result;
4720	struct timespec		my_timeout;
4721	int					my_fd_list[ AIO_TESTS_OUR_COUNT ];
4722	char *				my_buffers[ AIO_TESTS_OUR_COUNT ];
4723	struct aiocb *		my_aiocb_list[ AIO_TESTS_OUR_COUNT ];
4724	struct aiocb		my_aiocbs[ AIO_TESTS_OUR_COUNT ];
4725	char *				my_file_paths[ AIO_TESTS_OUR_COUNT ];
4726	kern_return_t           my_kr;
4727
4728	/* set up to have the ability to fire off up to AIO_TESTS_OUR_COUNT async IOs at once */
4729	memset( &my_fd_list[0], 0xFF, sizeof( my_fd_list ) );
4730	memset( &my_buffers[0], 0x00, sizeof( my_buffers ) );
4731	memset( &my_aiocb_list[0], 0x00, sizeof( my_aiocb_list ) );
4732	memset( &my_file_paths[0], 0x00, sizeof( my_file_paths ) );
4733	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4734	    	my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_buffers[ i ], AIO_TESTS_BUFFER_SIZE, VM_FLAGS_ANYWHERE);
4735		if(my_kr != KERN_SUCCESS){
4736                	printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4737                	goto test_failed_exit;
4738       		}
4739
4740	        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file_paths[ i ], PATH_MAX, VM_FLAGS_ANYWHERE);
4741                if(my_kr != KERN_SUCCESS){
4742                        printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4743                        goto test_failed_exit;
4744                }
4745
4746		my_pathp = my_file_paths[ i ];
4747		*my_pathp = 0x00;
4748		strcat( my_pathp, &g_target_path[0] );
4749		strcat( my_pathp, "/" );
4750
4751		/* create a test file */
4752		my_err = create_random_name( my_pathp, 1 );
4753		if ( my_err != 0 ) {
4754			goto test_failed_exit;
4755		}
4756		my_fd_list[ i ] = open( my_pathp, O_RDWR, 0 );
4757		if ( my_fd_list[ i ] <= 0 ) {
4758			printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4759			goto test_failed_exit;
4760		}
4761
4762		my_aiocbp = &my_aiocbs[ i ];
4763		my_aiocb_list[ i ] = my_aiocbp;
4764		memset( my_aiocbp, 0x00, sizeof( *my_aiocbp ) );
4765		my_aiocbp->aio_fildes = my_fd_list[ i ];
4766		my_aiocbp->aio_buf = (char *) my_buffers[ i ];
4767		my_aiocbp->aio_nbytes = 1024;
4768		my_aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; // no signals at completion;
4769		my_aiocbp->aio_sigevent.sigev_signo = 0;
4770	}
4771
4772	/* test direct IO (F_NOCACHE) and aio_write */
4773	my_err = fcntl( my_fd_list[ 0 ], F_NOCACHE, 1 );
4774	if ( my_err != 0 ) {
4775		printf( "malloc failed with error %d - \"%s\" \n", errno, strerror( errno) );
4776		goto test_failed_exit;
4777	}
4778
4779	my_aiocbp = &my_aiocbs[ 0 ];
4780    my_aiocbp->aio_fildes = my_fd_list[ 0 ];
4781	my_aiocbp->aio_offset = 4096;
4782	my_aiocbp->aio_buf = my_buffers[ 0 ];
4783    my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE;
4784    my_aiocbp->aio_reqprio = 0;
4785    my_aiocbp->aio_sigevent.sigev_notify = 0;
4786    my_aiocbp->aio_sigevent.sigev_signo = 0;
4787    my_aiocbp->aio_sigevent.sigev_value.sival_int = 0;
4788    my_aiocbp->aio_sigevent.sigev_notify_function = NULL;
4789    my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL;
4790    my_aiocbp->aio_lio_opcode = 0;
4791
4792	/* write some data */
4793	memset( my_buffers[ 0 ], 'j', AIO_TESTS_BUFFER_SIZE );
4794    my_err = aio_write( my_aiocbp );
4795	if ( my_err != 0 ) {
4796		printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4797		goto test_failed_exit;
4798	}
4799
4800    while ( 1 ) {
4801        my_err = aio_error( my_aiocbp );
4802        if ( my_err == EINPROGRESS ) {
4803            /* wait for IO to complete */
4804            sleep( 1 );
4805            continue;
4806        }
4807        else if ( my_err == 0 ) {
4808            ssize_t		my_result;
4809            my_result = aio_return( my_aiocbp );
4810            break;
4811        }
4812        else {
4813			printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4814			goto test_failed_exit;
4815        }
4816    } /* while loop */
4817
4818	/* read some data */
4819	memset( my_buffers[ 0 ], 'x', AIO_TESTS_BUFFER_SIZE );
4820    my_err = aio_read( my_aiocbp );
4821
4822    while ( 1 ) {
4823        my_err = aio_error( my_aiocbp );
4824        if ( my_err == EINPROGRESS ) {
4825            /* wait for IO to complete */
4826            sleep( 1 );
4827            continue;
4828        }
4829        else if ( my_err == 0 ) {
4830            ssize_t		my_result;
4831            my_result = aio_return( my_aiocbp );
4832
4833			if ( *(my_buffers[ 0 ]) != 'j' || *(my_buffers[ 0 ] + AIO_TESTS_BUFFER_SIZE - 1) != 'j' ) {
4834				printf( "aio_read or aio_write failed - wrong data read \n" );
4835				goto test_failed_exit;
4836			}
4837            break;
4838        }
4839        else {
4840			printf( "aio_read failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4841			goto test_failed_exit;
4842        }
4843    } /* while loop */
4844
4845	/* test aio_fsync */
4846	close( my_fd_list[ 0 ] );
4847	my_fd_list[ 0 ] = open( my_pathp, O_RDWR, 0 );
4848	if ( my_fd_list[ 0 ] == -1 ) {
4849		printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4850		goto test_failed_exit;
4851	}
4852
4853	my_aiocbp = &my_aiocbs[ 0 ];
4854    my_aiocbp->aio_fildes = my_fd_list[ 0 ];
4855    my_aiocbp->aio_offset = 0;
4856    my_aiocbp->aio_buf = my_buffers[ 0 ];
4857    my_aiocbp->aio_nbytes = 1024;
4858    my_aiocbp->aio_reqprio = 0;
4859    my_aiocbp->aio_sigevent.sigev_notify = 0;
4860    my_aiocbp->aio_sigevent.sigev_signo = 0;
4861    my_aiocbp->aio_sigevent.sigev_value.sival_int = 0;
4862    my_aiocbp->aio_sigevent.sigev_notify_function = NULL;
4863    my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL;
4864    my_aiocbp->aio_lio_opcode = 0;
4865
4866	/* write some data */
4867	memset( my_buffers[ 0 ], 'e', 1024 );
4868    my_err = aio_write( my_aiocbp );
4869	if ( my_err != 0 ) {
4870		printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4871		goto test_failed_exit;
4872	}
4873    while ( 1 ) {
4874        my_err = aio_error( my_aiocbp );
4875        if ( my_err == EINPROGRESS ) {
4876            /* wait for IO to complete */
4877            sleep( 1 );
4878            continue;
4879        }
4880        else if ( my_err == 0 ) {
4881            ssize_t		my_result;
4882            my_result = aio_return( my_aiocbp );
4883            break;
4884        }
4885        else {
4886			printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4887			goto test_failed_exit;
4888        }
4889    } /* while loop */
4890
4891	my_err = aio_fsync( O_SYNC, my_aiocbp );
4892	if ( my_err != 0 ) {
4893		printf( "aio_fsync failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4894		goto test_failed_exit;
4895	}
4896    while ( 1 ) {
4897        my_err = aio_error( my_aiocbp );
4898        if ( my_err == EINPROGRESS ) {
4899            /* wait for IO to complete */
4900            sleep( 1 );
4901            continue;
4902        }
4903        else if ( my_err == 0 ) {
4904			aio_return( my_aiocbp );
4905            break;
4906        }
4907        else {
4908			printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4909			goto test_failed_exit;
4910        }
4911    } /* while loop */
4912
4913	/* validate write */
4914	memset( my_buffers[ 0 ], 0x20, 16 );
4915	lseek( my_fd_list[ 0 ], 0, SEEK_SET );
4916	my_result = read( my_fd_list[ 0 ], my_buffers[ 0 ], 16);
4917	if ( my_result == -1 ) {
4918		printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4919		goto test_failed_exit;
4920	}
4921	if ( *(my_buffers[ 0 ]) != 'e' || *(my_buffers[ 0 ] + 16 - 1) != 'e' ) {
4922		printf( "aio_fsync or aio_write failed - wrong data read \n" );
4923		goto test_failed_exit;
4924	}
4925
4926	/* test aio_suspend and lio_listio */
4927	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4928		memset( my_buffers[ i ], 'a', AIO_TESTS_BUFFER_SIZE );
4929		my_aiocbp = &my_aiocbs[ i ];
4930		my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE;
4931		my_aiocbp->aio_lio_opcode = LIO_WRITE;
4932	}
4933    my_err = lio_listio( LIO_NOWAIT, my_aiocb_list, AIO_TESTS_OUR_COUNT, NULL );
4934	if ( my_err != 0 ) {
4935		printf( "lio_listio call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4936		goto test_failed_exit;
4937	}
4938
4939	my_timeout.tv_sec = 1;
4940	my_timeout.tv_nsec = 0;
4941	my_err = aio_suspend( (const struct aiocb *const*) my_aiocb_list, AIO_TESTS_OUR_COUNT, &my_timeout );
4942	if ( my_err != 0 ) {
4943		printf( "aio_suspend call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4944		goto test_failed_exit;
4945	}
4946
4947	/* test aio_cancel */
4948	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4949		my_aiocbp = &my_aiocbs[ i ];
4950		my_err = aio_cancel( my_aiocbp->aio_fildes, my_aiocbp );
4951		if ( my_err != AIO_ALLDONE && my_err != AIO_CANCELED && my_err != AIO_NOTCANCELED ) {
4952			printf( "aio_cancel failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4953			goto test_failed_exit;
4954		}
4955	}
4956
4957	my_err = 0;
4958	goto test_passed_exit;
4959
4960test_failed_exit:
4961	my_err = -1;
4962
4963test_passed_exit:
4964	for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4965		if ( my_fd_list[ i ] != -1 ) {
4966			close( my_fd_list[ i ] );
4967			my_fd_list[ i ] = -1;
4968		}
4969		if ( my_file_paths[ i ] != NULL ) {
4970			remove( my_file_paths[ i ] );
4971			vm_deallocate(mach_task_self(), (vm_address_t)my_file_paths[ i ], PATH_MAX);
4972			my_file_paths[ i ] = NULL;
4973		}
4974		if ( my_buffers[ i ] != NULL ) {
4975			vm_deallocate(mach_task_self(), (vm_address_t)my_buffers[ i ], AIO_TESTS_BUFFER_SIZE);
4976			my_buffers[ i ] = NULL;
4977		}
4978	}
4979	return( my_err );
4980}
4981
4982
4983/*  **************************************************************************************************************
4984 *	Test msgctl, msgget, msgrcv, msgsnd system calls.
4985 *  **************************************************************************************************************
4986 */
4987int message_queue_tests( void * the_argp )
4988{
4989#if !TARGET_OS_EMBEDDED
4990	int					my_err;
4991	int					my_msg_queue_id = -1;
4992	ssize_t				my_result;
4993	struct msqid_ds		my_msq_ds;
4994	struct testing_msq_message {
4995		long	msq_type;
4996		char	msq_buffer[ 32 ];
4997	}					my_msg;
4998
4999	/* get a message queue established for our use */
5000	my_msg_queue_id = msgget( IPC_PRIVATE, (IPC_CREAT | IPC_EXCL | IPC_R | IPC_W) );
5001	if ( my_msg_queue_id == -1 ) {
5002		printf( "msgget failed with errno %d - %s \n", errno, strerror( errno ) );
5003		goto test_failed_exit;
5004	}
5005
5006	/* get some stats on our message queue */
5007	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
5008	if ( my_err == -1 ) {
5009		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
5010		goto test_failed_exit;
5011	}
5012	if ( my_msq_ds.msg_perm.cuid != geteuid( ) ) {
5013		printf( "msgctl IPC_STAT failed to get correct creator uid \n" );
5014		goto test_failed_exit;
5015	}
5016	if ( (my_msq_ds.msg_perm.mode & (IPC_R | IPC_W)) == 0 ) {
5017		printf( "msgctl IPC_STAT failed to get correct mode \n" );
5018		goto test_failed_exit;
5019	}
5020
5021	/* put a message into our queue */
5022	my_msg.msq_type = 1;
5023	strcpy( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" );
5024	my_err = msgsnd( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0 );
5025	if ( my_err == -1 ) {
5026		printf( "msgsnd failed with errno %d - %s \n", errno, strerror( errno ) );
5027		goto test_failed_exit;
5028	}
5029
5030	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
5031	if ( my_err == -1 ) {
5032		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
5033		goto test_failed_exit;
5034	}
5035	if ( my_msq_ds.msg_qnum != 1 ) {
5036		printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5037		goto test_failed_exit;
5038	}
5039
5040	/* pull message off the queue */
5041	bzero( (void *)&my_msg, sizeof( my_msg ) );
5042	my_result = msgrcv( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0, 0 );
5043	if ( my_result == -1 ) {
5044		printf( "msgrcv failed with errno %d - %s \n", errno, strerror( errno ) );
5045		goto test_failed_exit;
5046	}
5047	if ( my_result != sizeof( my_msg.msq_buffer ) ) {
5048		printf( "msgrcv failed to return the correct number of bytes in our buffer \n" );
5049		goto test_failed_exit;
5050	}
5051	if ( strcmp( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ) != 0 ) {
5052		printf( "msgrcv failed to get the correct message \n" );
5053		goto test_failed_exit;
5054	}
5055
5056	my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
5057	if ( my_err == -1 ) {
5058		printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
5059		goto test_failed_exit;
5060	}
5061	if ( my_msq_ds.msg_qnum != 0 ) {
5062		printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5063		goto test_failed_exit;
5064	}
5065
5066	/* tear down the message queue */
5067	my_err = msgctl( my_msg_queue_id, IPC_RMID, NULL );
5068	if ( my_err == -1 ) {
5069		printf( "msgctl IPC_RMID failed with errno %d - %s \n", errno, strerror( errno ) );
5070		goto test_failed_exit;
5071	}
5072	my_msg_queue_id = -1;
5073
5074	my_err = 0;
5075	goto test_passed_exit;
5076
5077test_failed_exit:
5078	my_err = -1;
5079
5080test_passed_exit:
5081	if ( my_msg_queue_id != -1 ) {
5082		msgctl( my_msg_queue_id, IPC_RMID, NULL );
5083	}
5084	return( my_err );
5085#else
5086	printf( "\t--> Not supported on EMBEDDED TARGET \n" );
5087	return 0;
5088#endif
5089}
5090
5091
5092
5093/*  **************************************************************************************************************
5094 *	Test execution from data and stack areas.
5095 *  **************************************************************************************************************
5096 */
5097int data_exec_tests( void * the_argp )
5098{
5099	int my_err = 0;
5100	int arch, bits;
5101	posix_spawnattr_t attrp;
5102	char *argv[] = { "helpers/data_exec32nonxspawn", NULL };
5103
5104	int my_pid, my_status, ret;
5105
5106	if ((arch = get_architecture()) == -1) {
5107		printf("data_exec_test: couldn't determine architecture\n");
5108		goto test_failed_exit;
5109	}
5110
5111	bits = get_bits();
5112
5113	/*
5114	 * If the machine is 64-bit capable, run both the 32 and 64 bit versions of the test.
5115	 * Otherwise, just run the 32-bit version.
5116	 */
5117
5118	if (arch == INTEL) {
5119		if (bits == 64) {
5120			if (system("arch -arch x86_64 helpers/data_exec") != 0) {
5121				printf("data_exec-x86_64 failed\n");
5122				goto test_failed_exit;
5123			}
5124		}
5125
5126		if (system("arch -arch i386 helpers/data_exec") != 0) {
5127			printf("data_exec-i386 failed\n");
5128			goto test_failed_exit;
5129		}
5130
5131		posix_spawnattr_init(&attrp);
5132		posix_spawnattr_setflags(&attrp, _POSIX_SPAWN_ALLOW_DATA_EXEC );
5133		ret = posix_spawn(&my_pid, "helpers/data_exec32nonxspawn", NULL, &attrp, argv, NULL);
5134		if (ret) {
5135			printf("data_exec-i386 failed in posix_spawn %s\n", strerror(errno));
5136			goto test_failed_exit;
5137		}
5138		ret = wait4(my_pid, &my_status, 0, NULL);
5139		if (ret == -1) {
5140			printf("data_exec-i386 wait4 failed with errno %d - %s\n", errno, strerror(errno));
5141			goto test_failed_exit;
5142		}
5143		if (WEXITSTATUS(my_status) != 0) {
5144			printf("data_exec-i386 _POSIX_SPAWN_ALLOW_DATA_EXEC failed\n");
5145			goto test_failed_exit;
5146		}
5147	}
5148
5149	/* Add new architectures here similar to the above. */
5150
5151	goto test_passed_exit;
5152
5153test_failed_exit:
5154	my_err = -1;
5155
5156test_passed_exit:
5157	return my_err;
5158}
5159
5160/*  **************************************************************************************************************
5161 *	Test KASLR-related functionality
5162 *  **************************************************************************************************************
5163 */
5164int kaslr_test( void * the_argp )
5165{
5166	int result = 0;
5167	uint64_t slide = 0;
5168	size_t size;
5169	int slide_enabled;
5170
5171	size = sizeof(slide_enabled);
5172	result = sysctlbyname("kern.slide", &slide_enabled, &size, NULL, 0);
5173	if (result != 0) {
5174		printf("sysctlbyname(\"kern.slide\") failed with errno %d\n", errno);
5175		goto test_failed_exit;
5176	}
5177
5178	/* Test positive case first */
5179	size = sizeof(slide);
5180	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size);
5181	if (result == 0) {
5182		/* syscall supported, slide must be non-zero if running latest xnu and KASLR is enabled */
5183		if (slide_enabled && (slide == 0)) {
5184			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported slide of 0x%016llx\n", slide);
5185			goto test_failed_exit;
5186		}
5187		if (size != sizeof(slide)) {
5188			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported size of %lu\n", size);
5189			goto test_failed_exit;
5190		}
5191	} else {
5192		/* Only ENOTSUP is allowed. If so, assume all calls will be unsupported */
5193		if (errno == ENOTSUP) {
5194			return 0;
5195		} else {
5196			printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) returned unexpected errno (errno %d)\n", errno);
5197			goto test_failed_exit;
5198		}
5199	}
5200
5201	/* Negative cases for expected failures */
5202	size = sizeof(slide);
5203	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, &size);
5204	if ((result == 0) || (errno != EFAULT)) {
5205		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5206		goto test_failed_exit;
5207	}
5208
5209	size = sizeof(slide) + 1; /* EINVAL */
5210	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size);
5211	if ((result == 0) || (errno != EINVAL)) {
5212		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size+1) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5213		goto test_failed_exit;
5214	}
5215
5216	result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, NULL /* EFAULT */);
5217	if ((result == 0) || (errno != EFAULT)) {
5218		printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, NULL) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5219		goto test_failed_exit;
5220	}
5221
5222	size = sizeof(slide);
5223	result = kas_info(KAS_INFO_MAX_SELECTOR /* EINVAL */, &slide, &size);
5224	if ((result == 0) || (errno != EINVAL)) {
5225		printf("kas_info(KAS_INFO_MAX_SELECTOR, &slide, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
5226		goto test_failed_exit;
5227	}
5228
5229	return 0;
5230
5231test_failed_exit:
5232	return -1;
5233}
5234
5235#if TEST_SYSTEM_CALLS
5236
5237/*  **************************************************************************************************************
5238 *	Test xxxxxxxxx system calls.
5239 *  **************************************************************************************************************
5240 */
5241int sample_test( void * the_argp )
5242{
5243	int			my_err;
5244	int			my_fd = -1;
5245	char *		my_pathp = NULL;
5246	kern_return_t           my_kr;
5247
5248        my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5249        if(my_kr != KERN_SUCCESS){
5250                  printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5251                  goto test_failed_exit;
5252        }
5253
5254	*my_pathp = 0x00;
5255	strcat( my_pathp, &g_target_path[0] );
5256	strcat( my_pathp, "/" );
5257
5258	/* create a test file */
5259	my_err = create_random_name( my_pathp, 1 );
5260	if ( my_err != 0 ) {
5261		goto test_failed_exit;
5262	}
5263
5264	/* add your test code here... */
5265
5266
5267	my_err = 0;
5268	goto test_passed_exit;
5269
5270test_failed_exit:
5271	my_err = -1;
5272
5273test_passed_exit:
5274	if ( my_fd != -1 )
5275		close( my_fd );
5276	if ( my_pathp != NULL ) {
5277		remove( my_pathp );
5278		vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
5279	 }
5280	return( my_err );
5281}
5282
5283#endif
5284