]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/xnu_quick_test/tests.c
xnu-1699.22.73.tar.gz
[apple/xnu.git] / tools / tests / xnu_quick_test / tests.c
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 <AvailabilityMacros.h> /* for determination of Mac OS X version (tiger, leopard, etc.) */
16 #include <libkern/OSByteOrder.h> /* for OSSwap32() */
17 #include <mach/mach.h>
18
19
20 extern char g_target_path[ PATH_MAX ];
21 extern int g_skip_setuid_tests;
22 extern int g_is_single_user;
23
24
25 void print_acct_debug_strings( char * my_ac_comm );
26
27
28 #if TEST_SYSTEM_CALLS /* system calls to do */
29 "reboot", /* 55 = reboot */
30 "revoke", /* 56 = revoke */
31 "sbrk", /* 69 = sbrk */
32 "sstk", /* 70 = sstk */
33 "mount", /* 167 = mount */
34 "unmount", /* 159 = unmount */
35 "undelete", /* 205 = undelete */
36 "watchevent", /* 231 = watchevent */
37 "waitevent", /* 232 = waitevent */
38 "modwatch", /* 233 = modwatch */
39 "fsctl", /* 242 = fsctl */
40 "initgroups", /* 243 = initgroups */
41 "semsys", /* 251 = semsys */
42 "semconfig", /* 257 = semconfig */
43 "msgsys", /* 252 = msgsys */
44 "shmsys", /* 253 = shmsys */
45 "load_shared_file", /* 296 = load_shared_file */
46 "reset_shared_file", /* 297 = reset_shared_file */
47 "new_system_shared_regions", /* 298 = new_system_shared_regions */
48 "shared_region_map_file_np", /* 299 = shared_region_map_file_np */
49 "shared_region_make_private_np", /* 300 = shared_region_make_private_np */
50 "__pthread_kill", /* 328 = __pthread_kill */
51 "pthread_sigmask", /* 329 = pthread_sigmask */
52 "__disable_threadsignal", /* 331 = __disable_threadsignal */
53 "__pthread_markcancel", /* 332 = __pthread_markcancel */
54 "__pthread_canceled", /* 333 = __pthread_canceled */
55 "__semwait_signal", /* 334 = __semwait_signal */
56 "audit", /* 350 = audit */
57 "auditon", /* 351 = auditon */
58 "getaudit", /* 355 = getaudit */
59 "setaudit", /* 356 = setaudit */
60 "getaudit_addr", /* 357 = getaudit_addr */
61 "setaudit_addr", /* 358 = setaudit_addr */
62 "auditctl", /* 359 = auditctl */
63 #endif
64
65 /* **************************************************************************************************************
66 * Test the syscall system call.
67 * **************************************************************************************************************
68 */
69 int syscall_test( void * the_argp )
70 {
71 int my_err;
72 int my_fd = -1;
73 char * my_pathp;
74 kern_return_t my_kr;
75
76 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
77 if(my_kr != KERN_SUCCESS){
78 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
79 goto test_failed_exit;
80 }
81
82 *my_pathp = 0x00;
83 strcpy( my_pathp, &g_target_path[0] );
84 strcat( my_pathp, "/" );
85
86 /* create a test file */
87 my_err = create_random_name( my_pathp, 1 );
88 if ( my_err != 0 ) {
89 goto test_failed_exit;
90 }
91
92 /* use an indirect system call to open our test file.
93 * I picked open since it uses a path pointer which grows to 64 bits in an LP64 environment.
94 */
95 my_fd = syscall( SYS_open, my_pathp, (O_RDWR | O_EXCL), 0 );
96 if ( my_fd == -1 ) {
97 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
98 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
99 goto test_failed_exit;
100 }
101
102 my_err = 0;
103 goto test_passed_exit;
104
105 test_failed_exit:
106 my_err = -1;
107
108 test_passed_exit:
109 if ( my_fd != -1 )
110 close( my_fd );
111 if ( my_pathp != NULL ) {
112 remove( my_pathp );
113 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
114 }
115 return( my_err );
116 }
117
118 /* **************************************************************************************************************
119 * Test fork wait4, and exit system calls.
120 * **************************************************************************************************************
121 */
122 int fork_wait4_exit_test( void * the_argp )
123 {
124 int my_err, my_status;
125 pid_t my_pid, my_wait_pid;
126 struct rusage my_usage;
127
128 /* spin off another process */
129 my_pid = fork( );
130 if ( my_pid == -1 ) {
131 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
132 return( -1 );
133 }
134 else if ( my_pid == 0 ) {
135 struct stat my_sb;
136
137 /* child process does very little then exits */
138 my_err = stat( &g_target_path[0], &my_sb );
139 if ( my_err != 0 ) {
140 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
141 printf( "\t path we stated \"%s\" \n", &g_target_path[0] );
142 exit( -1 );
143 }
144 exit( 44 );
145 }
146
147 /* parent process waits for child to exit */
148 my_wait_pid = wait4( my_pid, &my_status, 0, &my_usage );
149 if ( my_wait_pid == -1 ) {
150 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
151 return( -1 );
152 }
153
154 /* wait4 should return our child's pid when it exits */
155 if ( my_wait_pid != my_pid ) {
156 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
157 return( -1 );
158 }
159
160 /* kind of just guessing on these values so if this fails we should take a closer
161 * look at the returned rusage structure.
162 */
163 if ( my_usage.ru_utime.tv_sec > 1 || my_usage.ru_stime.tv_sec > 1 ||
164 my_usage.ru_majflt > 1000 || my_usage.ru_msgsnd > 100 ) {
165 printf( "wait4 returned an odd looking rusage structure \n" );
166 return( -1 );
167 }
168
169 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) == 44 ) {
170 }
171 else {
172 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
173 return( -1 );
174 }
175
176 return( 0 );
177 }
178
179 /* **************************************************************************************************************
180 * Test fsync, ftruncate, lseek, pread, pwrite, read, readv, truncate, write, writev system calls.
181 * **************************************************************************************************************
182 */
183 int read_write_test( void * the_argp )
184 {
185 int my_fd = -1;
186 int my_err;
187 char * my_pathp = NULL;
188 char * my_bufp = NULL;
189 ssize_t my_result;
190 off_t my_current_offset;
191 struct iovec my_iovs[2];
192 struct stat my_sb;
193 kern_return_t my_kr;
194
195 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
196 if(my_kr != KERN_SUCCESS){
197 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
198 goto test_failed_exit;
199 }
200
201 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, MY_BUFFER_SIZE, VM_FLAGS_ANYWHERE);
202 if(my_kr != KERN_SUCCESS){
203 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
204 goto test_failed_exit;
205 }
206
207 *my_pathp = 0x00;
208 strcat( my_pathp, &g_target_path[0] );
209 strcat( my_pathp, "/" );
210
211 /* create a test file */
212 my_err = create_random_name( my_pathp, 1 );
213 if ( my_err != 0 ) {
214 goto test_failed_exit;
215 }
216
217 my_fd = open( my_pathp, O_RDONLY, 0 );
218 if ( my_fd == -1 ) {
219 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
220 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
221 goto test_failed_exit;
222 }
223
224 /* should get EOF since the file is empty at this point */
225 my_result = read( my_fd, my_bufp, 10);
226 if ( my_result == -1 ) {
227 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
228 goto test_failed_exit;
229 }
230 if ( my_result != 0 ) {
231 if ( sizeof( ssize_t ) > sizeof( int ) ) {
232 printf( "read call failed - should have read 0 bytes on empty file - read %ld \n", (long int) my_result );
233 }
234 else {
235 printf( "read call failed - should have read 0 bytes on empty file - read %d \n", (int) my_result );
236 }
237 goto test_failed_exit;
238 }
239
240 /* this write should fail since we opened for read only */
241 my_result = write( my_fd, my_bufp, 10 );
242 my_err = errno;
243 if ( my_result != -1 ) {
244 if ( sizeof( ssize_t ) > sizeof( int ) ) {
245 printf( "write should have failed for read only fd - %ld \n", (long int) my_result );
246 }
247 else {
248 printf( "write should have failed for read only fd - %d \n", (int) my_result );
249 }
250 goto test_failed_exit;
251 }
252 if ( my_err != EBADF ) {
253 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
254 printf( "should have failed with EBADF error %d \n", EBADF );
255 goto test_failed_exit;
256 }
257
258 /* now really write some data */
259 close( my_fd );
260 my_fd = open( my_pathp, O_RDWR, 0 );
261 if ( my_fd == -1 ) {
262 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
263 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
264 goto test_failed_exit;
265 }
266
267 memset( my_bufp, 'j', MY_BUFFER_SIZE );
268 my_result = write( my_fd, my_bufp, MY_BUFFER_SIZE );
269 if ( my_result == -1 ) {
270 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
271 goto test_failed_exit;
272 }
273 if ( my_result != MY_BUFFER_SIZE ) {
274 printf( "write failed to write out all the data \n" );
275 goto test_failed_exit;
276 }
277
278 /* push data to disk */
279 my_err = fsync( my_fd );
280 if ( my_err == -1 ) {
281 printf( "fsync failed with errno %d - %s \n", errno, strerror( errno ) );
282 goto test_failed_exit;
283 }
284
285 /* now verify the write worked OK using readv */
286 lseek( my_fd, 0, SEEK_SET );
287 bzero( (void *)my_bufp, MY_BUFFER_SIZE );
288 my_iovs[0].iov_base = my_bufp;
289 my_iovs[0].iov_len = 16;
290 my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 16) ;
291 my_iovs[1].iov_len = 16;
292
293 my_result = readv( my_fd, &my_iovs[0], 2 );
294 if ( my_result == -1 ) {
295 printf( "readv call failed with error %d - \"%s\" \n", errno, strerror( errno) );
296 goto test_failed_exit;
297 }
298 if ( my_result != 32 ) {
299 printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result );
300 goto test_failed_exit;
301 }
302 if ( *my_bufp != 'j' || *(my_bufp + (MY_BUFFER_SIZE - 1)) != 'j' ) {
303 printf( "readv failed to get correct data \n" );
304 goto test_failed_exit;
305 }
306
307 /* test ftruncate */
308 my_err = ftruncate( my_fd, 0 );
309 if ( my_err == -1 ) {
310 printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
311 goto test_failed_exit;
312 }
313
314 my_err = fstat( my_fd, &my_sb );
315 if ( my_err == -1 ) {
316 printf( "fstat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
317 goto test_failed_exit;
318 }
319 if ( my_sb.st_size != 0 ) {
320 printf( "ftruncate call failed - file size is wrong \n" );
321 goto test_failed_exit;
322 }
323
324 /* test writev */
325 lseek( my_fd, 0, SEEK_SET );
326 memset( my_bufp, 'z', MY_BUFFER_SIZE );
327 my_iovs[0].iov_base = my_bufp;
328 my_iovs[0].iov_len = 8;
329 my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 8) ;
330 my_iovs[1].iov_len = 8;
331 my_result = writev( my_fd, &my_iovs[0], 2 );
332 if ( my_result == -1 ) {
333 printf( "writev call failed with error %d - \"%s\" \n", errno, strerror( errno) );
334 goto test_failed_exit;
335 }
336 if ( my_result != 16 ) {
337 printf( "writev failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result );
338 goto test_failed_exit;
339 }
340
341 /* now verify the writev worked OK */
342 lseek( my_fd, 0, SEEK_SET );
343 bzero( (void *)my_bufp, MY_BUFFER_SIZE );
344 my_iovs[0].iov_base = my_bufp;
345 my_iovs[0].iov_len = 8;
346 my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 8) ;
347 my_iovs[1].iov_len = 8;
348
349 my_result = readv( my_fd, &my_iovs[0], 2 );
350 if ( my_result == -1 ) {
351 printf( "readv call failed with error %d - \"%s\" \n", errno, strerror( errno) );
352 goto test_failed_exit;
353 }
354 if ( my_result != 16 ) {
355 printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result );
356 goto test_failed_exit;
357 }
358 if ( *my_bufp != 'z' || *(my_bufp + (MY_BUFFER_SIZE - 1)) != 'z' ) {
359 printf( "readv failed to get correct data \n" );
360 goto test_failed_exit;
361 }
362
363 /* test pread and pwrite */
364 my_current_offset = lseek( my_fd, 0, SEEK_CUR );
365 if ( my_current_offset == -1 ) {
366 printf( "lseek call failed with error %d - \"%s\" \n", errno, strerror( errno) );
367 goto test_failed_exit;
368 }
369
370 my_result = pwrite( my_fd, "jer", 3, my_current_offset );
371 if ( my_result == -1 ) {
372 printf( "pwrite call failed with error %d - \"%s\" \n", errno, strerror( errno) );
373 goto test_failed_exit;
374 }
375 if ( my_result != 3 ) {
376 printf( "pwrite failed to write all the data \n" );
377 goto test_failed_exit;
378 }
379
380 /* make sure file position did not advance */
381 if ( my_current_offset != lseek( my_fd, 0, SEEK_CUR ) ) {
382 printf( "pwrite advanced file positiion \n" );
383 goto test_failed_exit;
384 }
385
386 bzero( (void *)my_bufp, MY_BUFFER_SIZE );
387 my_result = pread( my_fd, my_bufp, 3, my_current_offset );
388 if ( my_result == -1 ) {
389 printf( "pread call failed with error %d - \"%s\" \n", errno, strerror( errno) );
390 goto test_failed_exit;
391 }
392 if ( my_result != 3 ) {
393 printf( "pread failed to write all the data \n" );
394 goto test_failed_exit;
395 }
396
397 /* make sure file position did not advance */
398 if ( my_current_offset != lseek( my_fd, 0, SEEK_CUR ) ) {
399 printf( "pread advanced file positiion \n" );
400 goto test_failed_exit;
401 }
402
403 /* make sure pread and pwrite transferred correct data */
404 if ( strcmp( my_bufp, "jer" ) != 0 ) {
405 printf( "pread or pwrite failed to read / write correct data \n" );
406 goto test_failed_exit;
407 }
408
409 /* test truncate */
410 my_err = truncate( my_pathp, 0 );
411 if ( my_err == -1 ) {
412 printf( "truncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
413 goto test_failed_exit;
414 }
415
416 my_err = stat( my_pathp, &my_sb );
417 if ( my_err == -1 ) {
418 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
419 goto test_failed_exit;
420 }
421 if ( my_sb.st_size != 0 ) {
422 printf( "truncate call failed - file size is wrong \n" );
423 goto test_failed_exit;
424 }
425
426 my_err = 0;
427 goto test_passed_exit;
428
429 test_failed_exit:
430 my_err = -1;
431
432 test_passed_exit:
433 if ( my_fd != -1 )
434 close( my_fd );
435 if ( my_pathp != NULL ) {
436 remove( my_pathp );
437 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
438 }
439 if ( my_bufp != NULL )
440 vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, MY_BUFFER_SIZE);
441 return( my_err );
442 }
443
444 /* **************************************************************************************************************
445 * Test close, fpathconf, fstat, open, pathconf system calls.
446 * **************************************************************************************************************
447 */
448 int open_close_test( void * the_argp )
449 {
450 int my_err;
451 int my_fd = -1;
452 char * my_pathp = NULL;
453 ssize_t my_result;
454 long my_pconf_result;
455 struct stat my_sb;
456 char my_buffer[32];
457 kern_return_t my_kr;
458
459 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
460 if(my_kr != KERN_SUCCESS){
461 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
462 goto test_failed_exit;
463 }
464
465 *my_pathp = 0x00;
466 strcat( my_pathp, &g_target_path[0] );
467 strcat( my_pathp, "/" );
468
469 /* create a test file */
470 my_err = create_random_name( my_pathp, 1 );
471 if ( my_err != 0 ) {
472 goto test_failed_exit;
473 }
474
475 /* test O_WRONLY case */
476 my_fd = open( my_pathp, O_WRONLY, 0 );
477 if ( my_fd == -1 ) {
478 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
479 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
480 goto test_failed_exit;
481 }
482
483 /* test pathconf and fpathconf */
484 my_pconf_result = pathconf( my_pathp, _PC_PATH_MAX );
485 if ( my_pconf_result == -1 ) {
486 printf( "pathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
487 goto test_failed_exit;
488 }
489 // printf( "_PC_PATH_MAX %ld \n", my_pconf_result );
490 /* results look OK? */
491 if ( my_pconf_result < PATH_MAX ) {
492 printf( "pathconf - _PC_PATH_MAX - looks like wrong results \n" );
493 goto test_failed_exit;
494 }
495
496 my_pconf_result = fpathconf( my_fd, _PC_NAME_MAX );
497 if ( my_pconf_result == -1 ) {
498 printf( "fpathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
499 goto test_failed_exit;
500 }
501 // printf( "_PC_NAME_MAX %ld \n", my_pconf_result );
502 /* results look OK? */
503 if ( my_pconf_result < 6 ) {
504 printf( "fpathconf - _PC_NAME_MAX - looks like wrong results \n" );
505 goto test_failed_exit;
506 }
507
508 /* write some data then try to read it */
509 my_result = write( my_fd, "kat", 3 );
510 my_err = errno;
511 if ( my_result != 3 ) {
512 if ( sizeof( ssize_t ) > sizeof( int ) ) {
513 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result );
514 }
515 else {
516 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result );
517 }
518 goto test_failed_exit;
519 }
520
521 /* Try to read - this should fail since we opened file with O_WRONLY */
522 my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
523 my_err = errno;
524 if ( my_result != -1 ) {
525 printf( "read call should have failed with errno 9 (EBADF) \n" );
526 goto test_failed_exit;
527 }
528 else if ( my_err != EBADF ) {
529 printf( "read call should have failed with errno 9 (EBADF). actually failed with %d - \"%s\" \n", my_err, strerror( my_err) );
530 goto test_failed_exit;
531 }
532
533 close( my_fd );
534
535 /* test O_TRUNC and O_APPEND case */
536 my_fd = open( my_pathp, (O_RDWR | O_TRUNC | O_APPEND), 0 );
537 if ( my_fd == -1 ) {
538 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
539 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
540 goto test_failed_exit;
541 }
542
543 my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
544 if ( my_result == -1 ) {
545 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
546 goto test_failed_exit;
547 }
548 if ( my_result != 0 ) {
549 printf( "read failed - should have read 0 bytes. \n" );
550 goto test_failed_exit;
551 }
552
553 my_result = write( my_fd, "kat", 3 );
554 my_err = errno;
555 if ( my_result != 3 ) {
556 if ( sizeof( ssize_t ) > sizeof( int ) ) {
557 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result );
558 }
559 else {
560 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result );
561 }
562 goto test_failed_exit;
563 }
564
565 /* add some more data to the test file - this should be appended */
566 lseek( my_fd, 0, SEEK_SET );
567 my_result = write( my_fd, "zzz", 3 );
568 my_err = errno;
569 if ( my_result != 3 ) {
570 if ( sizeof( ssize_t ) > sizeof( int ) ) {
571 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result );
572 }
573 else {
574 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result );
575 }
576 goto test_failed_exit;
577 }
578
579 /* now verify the writes */
580 bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
581 lseek( my_fd, 0, SEEK_SET );
582 my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
583 if ( my_result == -1 ) {
584 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
585 goto test_failed_exit;
586 }
587 if ( my_buffer[0] != 'k' || my_buffer[5] != 'z' ) {
588 printf( "read failed to get correct data \n" );
589 goto test_failed_exit;
590 }
591
592 /* test fstat */
593 my_err = fstat( my_fd, &my_sb );
594 if ( my_err == -1 ) {
595 printf( "fstat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
596 goto test_failed_exit;
597 }
598 if ( my_sb.st_size != 6 ) {
599 printf( "fstat call failed - st_size is wrong \n" );
600 goto test_failed_exit;
601 }
602 if ( !S_ISREG( my_sb.st_mode ) ) {
603 printf( "fstat call failed - st_mode does not indicate regular file \n" );
604 goto test_failed_exit;
605 }
606
607 my_err = 0;
608 goto test_passed_exit;
609
610 test_failed_exit:
611 my_err = -1;
612
613 test_passed_exit:
614 if ( my_fd != -1 )
615 close( my_fd );
616 if ( my_pathp != NULL ) {
617 remove( my_pathp );
618 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
619 }
620 return( my_err );
621 }
622
623 /* **************************************************************************************************************
624 * Test link, stat and unlink system calls.
625 * **************************************************************************************************************
626 */
627 int link_stat_unlink_test( void * the_argp )
628 {
629 int my_err;
630 int my_fd = -1;
631 char * my_pathp = NULL;
632 char * my_path2p = NULL;
633 nlink_t my_link_count;
634 ssize_t my_result;
635 struct stat my_sb;
636 kern_return_t my_kr;
637
638 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
639 if(my_kr != KERN_SUCCESS){
640 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
641 goto test_failed_exit;
642 }
643
644 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_path2p, PATH_MAX, VM_FLAGS_ANYWHERE);
645 if(my_kr != KERN_SUCCESS){
646 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
647 goto test_failed_exit;
648 }
649
650 *my_pathp = 0x00;
651 *my_path2p = 0x00;
652 strcat( my_pathp, &g_target_path[0] );
653 strcat( my_pathp, "/" );
654
655 /* create a test file */
656 my_err = create_random_name( my_pathp, 1 );
657 if ( my_err != 0 ) {
658 goto test_failed_exit;
659 }
660
661 /* now create a name for the link file */
662 strcat( my_path2p, my_pathp );
663 strcat( my_path2p, "link" );
664
665 /* get the current link count */
666 my_err = stat( my_pathp, &my_sb );
667 if ( my_err != 0 ) {
668 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
669 goto test_failed_exit;
670 }
671 my_link_count = my_sb.st_nlink;
672
673 /* check file size (should be 0) */
674 if ( my_sb.st_size != 0 ) {
675 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
676 printf( "st_size is not 0 \n" );
677 goto test_failed_exit;
678 }
679
680 /* change file size */
681 my_fd = open( my_pathp, O_RDWR, 0 );
682 if ( my_fd == -1 ) {
683 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
684 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp );
685 goto test_failed_exit;
686 }
687 my_result = write( my_fd, "kat", 3 );
688 my_err = errno;
689 if ( my_result != 3 ) {
690 if ( sizeof( ssize_t ) > sizeof( int ) ) {
691 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result );
692 }
693 else {
694 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result );
695 }
696 goto test_failed_exit;
697 }
698 close( my_fd );
699 my_fd = -1;
700
701 /* now link another file to our test file and recheck link count */
702 my_err = link( my_pathp, my_path2p );
703 if ( my_err != 0 ) {
704 printf( "link call failed. got errno %d - %s. \n", errno, strerror( errno ) );
705 goto test_failed_exit;
706 }
707 my_err = stat( my_pathp, &my_sb );
708 if ( my_err != 0 ) {
709 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
710 goto test_failed_exit;
711 }
712 if ( (my_link_count + 1) != my_sb.st_nlink ) {
713 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
714 printf( "incorrect st_nlink \n" );
715 goto test_failed_exit;
716 }
717
718 /* check file size (should be 3) */
719 if ( my_sb.st_size != 3 ) {
720 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
721 printf( "st_size is not 3 \n" );
722 goto test_failed_exit;
723 }
724
725 /* now make sure unlink works OK */
726 my_err = unlink( my_path2p );
727 if ( my_err != 0 ) {
728 printf( "unlink call failed. got errno %d - %s. \n", errno, strerror( errno ) );
729 goto test_failed_exit;
730 }
731 my_err = stat( my_pathp, &my_sb );
732 if ( my_err != 0 ) {
733 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
734 goto test_failed_exit;
735 }
736 if ( my_link_count != my_sb.st_nlink ) {
737 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp );
738 printf( "incorrect st_nlink \n" );
739 goto test_failed_exit;
740 }
741
742 my_err = 0;
743 goto test_passed_exit;
744
745 test_failed_exit:
746 my_err = -1;
747
748 test_passed_exit:
749 if ( my_fd != -1 )
750 close( my_fd );
751 if ( my_pathp != NULL ) {
752 remove( my_pathp );
753 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
754 }
755 if ( my_path2p != NULL ) {
756 remove( my_path2p );
757 vm_deallocate(mach_task_self(), (vm_address_t)my_path2p, PATH_MAX);
758 }
759 return( my_err );
760 }
761
762 /* **************************************************************************************************************
763 * Test chdir and fchdir system calls.
764 * **************************************************************************************************************
765 */
766 int chdir_fchdir_test( void * the_argp )
767 {
768 int my_err;
769 int my_fd = -1;
770 char * my_pathp = NULL;
771 char * my_file_namep;
772 struct stat my_sb;
773 struct stat my_sb2;
774 kern_return_t my_kr;
775
776 char *cwd = getwd(NULL); /* Save current working directory so we can restore later */
777
778 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
779 if(my_kr != KERN_SUCCESS){
780 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
781 goto test_failed_exit;
782 }
783
784 *my_pathp = 0x00;
785 strcat( my_pathp, &g_target_path[0] );
786 strcat( my_pathp, "/" );
787
788 /* create a test file */
789 my_err = create_random_name( my_pathp, 1 );
790 if ( my_err != 0 ) {
791 goto test_failed_exit;
792 }
793
794 /* test by doing a stat on the test file using a full path and a partial path.
795 * get full path first.
796 */
797 my_err = stat( my_pathp, &my_sb );
798 if ( my_err != 0 ) {
799 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
800 goto test_failed_exit;
801 }
802
803 /* now do the chdir to our test directory and then do the stat relative to that location */
804 my_err = chdir( &g_target_path[0] );
805 if ( my_err != 0 ) {
806 printf( "chdir call failed. got errno %d - %s. \n", errno, strerror( errno ) );
807 goto test_failed_exit;
808 }
809
810 my_file_namep = strrchr( my_pathp, '/' );
811 my_file_namep++;
812 my_err = stat( my_file_namep, &my_sb2 );
813 if ( my_err != 0 ) {
814 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
815 goto test_failed_exit;
816 }
817
818 /* both stat buffers should contain the same data since they should be referencing the same
819 * file.
820 */
821 if ( my_sb.st_ino != my_sb2.st_ino || my_sb.st_size != my_sb2.st_size ||
822 my_sb.st_mtimespec.tv_sec != my_sb2.st_mtimespec.tv_sec ||
823 my_sb.st_mtimespec.tv_nsec != my_sb2.st_mtimespec.tv_nsec ) {
824 printf( "chdir call appears to have failed. stat buffer contents do not match! \n" );
825 goto test_failed_exit;
826 }
827
828 /* now change our current directory to "/" and use fchdir to get back to our test directory */
829 my_err = chdir( "/" );
830 if ( my_err != 0 ) {
831 printf( "chdir call failed. got errno %d - %s. \n", errno, strerror( errno ) );
832 goto test_failed_exit;
833 }
834
835 /* we should not find our test file at the root of the volume */
836 my_err = stat( my_file_namep, &my_sb2 );
837 if ( my_err == 0 ) {
838 printf( "chdir to root volume has failed \n" );
839 goto test_failed_exit;
840 }
841
842 /* get a file descriptor to the test directory for use with fchdir */
843 my_fd = open( &g_target_path[0], O_RDONLY, 0 );
844 if ( my_fd == -1 ) {
845 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
846 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
847 goto test_failed_exit;
848 }
849
850 my_err = fchdir( my_fd );
851 if ( my_err == -1 ) {
852 printf( "fchdir call failed. got errno %d - %s. \n", errno, strerror( errno ) );
853 goto test_failed_exit;
854 }
855
856 my_err = stat( my_file_namep, &my_sb2 );
857 if ( my_err != 0 ) {
858 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
859 goto test_failed_exit;
860 }
861
862 /* both stat buffers should contain the same data since they should be referencing the same
863 * file.
864 */
865 if ( my_sb.st_ino != my_sb2.st_ino || my_sb.st_size != my_sb2.st_size ||
866 my_sb.st_mtimespec.tv_sec != my_sb2.st_mtimespec.tv_sec ||
867 my_sb.st_mtimespec.tv_nsec != my_sb2.st_mtimespec.tv_nsec ) {
868 printf( "chdir call appears to have failed. stat buffer contents do not match! \n" );
869 goto test_failed_exit;
870 }
871
872 my_err = 0;
873 goto test_passed_exit;
874
875 test_failed_exit:
876 my_err = -1;
877
878 test_passed_exit:
879 if ( my_fd != -1 )
880 close( my_fd );
881 if ( my_pathp != NULL ) {
882 remove( my_pathp );
883 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
884 }
885 if ( chdir(cwd) != 0) /* Changes back to original directory, don't screw up the env. */
886 my_err = -1;
887 return( my_err );
888 }
889
890 /* **************************************************************************************************************
891 * Test access, chmod and fchmod system calls.
892 * **************************************************************************************************************
893 */
894 int access_chmod_fchmod_test( void * the_argp )
895 {
896 int my_err;
897 int my_fd = -1;
898 char * my_pathp = NULL;
899 uid_t euid,ruid;
900 struct stat my_sb;
901 kern_return_t my_kr;
902
903 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
904 if(my_kr != KERN_SUCCESS){
905 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
906 goto test_failed_exit;
907 }
908
909 *my_pathp = 0x00;
910 strcat( my_pathp, &g_target_path[0] );
911 strcat( my_pathp, "/" );
912
913 /* create a test file */
914 my_err = create_random_name( my_pathp, 1 );
915 if ( my_err != 0 ) {
916 goto test_failed_exit;
917 }
918
919
920 /* test chmod */
921 my_err = chmod( my_pathp, S_IRWXU );
922 if ( my_err == -1 ) {
923 printf( "chmod call failed. got errno %d - %s. \n", errno, strerror( errno ) );
924 goto test_failed_exit;
925 }
926
927 my_err = chmod( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) );
928 if ( my_err == -1 ) {
929 printf( "chmod call failed. got errno %d - %s. \n", errno, strerror( errno ) );
930 goto test_failed_exit;
931 }
932
933 /* test access - this should fail */
934 my_err = access( my_pathp, (X_OK) );
935 if ( my_err == 0 ) {
936 printf( "access call should have failed, but did not. \n" );
937 goto test_failed_exit;
938 }
939 else if ( my_err == -1 ) {
940 int tmp = 0;
941 tmp = getuid( );
942
943 /* special case when running as root - we get back EPERM when running as root */
944 my_err = errno;
945 if ( ( tmp == 0 && my_err != EPERM) || (tmp != 0 && my_err != EACCES) ) {
946 printf( "access failed with errno %d - %s. \n", my_err, strerror( my_err ) );
947 goto test_failed_exit;
948 }
949 }
950
951 /* verify correct modes are set */
952 my_err = stat( my_pathp, &my_sb );
953 if ( my_err != 0 ) {
954 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
955 goto test_failed_exit;
956 }
957
958 if ( (my_sb.st_mode & (S_IRWXO | S_IXGRP)) != 0 ||
959 (my_sb.st_mode & (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == 0 ) {
960 printf( "chmod call appears to have failed. stat shows incorrect values in st_mode! \n" );
961 goto test_failed_exit;
962 }
963
964
965 /* another test for the access system call -- refer ro radar# 6725311 */
966
967 system("touch /tmp/me");
968 system("echo local | sudo touch /tmp/notme");
969
970 euid = geteuid();
971 ruid = getuid();
972 //printf("effective user id is %d: and real user id is %d: \n", (int)euid, (int)ruid);
973 setreuid(ruid, ruid);
974 //printf("effective user id is %d: and real user id is %d: \n", (int)geteuid, (int)getuid);
975 my_err = unlink(FILE_NOTME);
976 if (my_err < 0) {
977 my_err = errno;
978 }
979 if (my_err == 0) {
980 printf("Unresolved: First attempt deleted '" FILE_NOTME "'! \n" );
981 goto test_failed_exit;
982 } else {
983 printf("Status: First attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
984
985 if (true) {
986 my_err = access(FILE_ME, _DELETE_OK);
987 if (my_err < 0) {
988 my_err = errno;
989 }
990 //printf("Status: access('" FILE_ME "') = %d - %s.\n", my_err, strerror( my_err ));
991 fprintf(stderr, "Status: access('" FILE_ME "') = %d\n", my_err);
992 }
993 my_err = unlink(FILE_NOTME);
994 if (my_err < 0) {
995 my_err = errno;
996 }
997 if (my_err == 0) {
998 printf("Failed: Second attempt deleted '" FILE_NOTME "'!\n");
999 //fprintf(stderr, "Failed: Second attempt deleted '" FILE_NOTME "'!\n");
1000 goto test_failed_exit;
1001 } else {
1002 printf("Passed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err ));
1003 // fprintf(stderr, "Passed: Second attempt to delete '" FILE_NOTME "' failed with error %d\n", my_err);
1004
1005 }
1006 }
1007 setreuid(ruid, euid);
1008 //printf("effective user id is %d: and real user id is %d ---1: \n", euid, ruid);
1009 /* end of test*/
1010
1011
1012 /* test fchmod */
1013 my_fd = open( my_pathp, O_RDONLY, 0 );
1014 if ( my_fd == -1 ) {
1015 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1016 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
1017 goto test_failed_exit;
1018 }
1019
1020 my_err = fchmod( my_fd, S_IRWXU );
1021 if ( my_err == -1 ) {
1022 printf( "fchmod call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1023 goto test_failed_exit;
1024 }
1025
1026 my_err = stat( my_pathp, &my_sb );
1027 if ( my_err != 0 ) {
1028 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1029 goto test_failed_exit;
1030 }
1031
1032 /* verify correct modes are set */
1033 if ( (my_sb.st_mode & (S_IRWXG | S_IRWXO)) != 0 ||
1034 (my_sb.st_mode & (S_IRWXU)) == 0 ) {
1035 printf( "fchmod call appears to have failed. stat shows incorrect values in st_mode! \n" );
1036 goto test_failed_exit;
1037 }
1038
1039 my_err = 0;
1040 goto test_passed_exit;
1041
1042 test_failed_exit:
1043 my_err = -1;
1044
1045 test_passed_exit:
1046 if ( my_fd != -1 )
1047 close( my_fd );
1048 if ( my_pathp != NULL ) {
1049 remove( my_pathp );
1050 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1051 }
1052 return( my_err );
1053 }
1054
1055 /* **************************************************************************************************************
1056 * Test chown, fchown, lchown, lstat, readlink, symlink system calls.
1057 * **************************************************************************************************************
1058 */
1059 int chown_fchown_lchown_lstat_symlink_test( void * the_argp )
1060 {
1061 #if !TARGET_OS_EMBEDDED
1062 int my_err, my_group_count, i;
1063 int my_fd = -1;
1064 char * my_pathp = NULL;
1065 char * my_link_pathp = NULL;
1066 uid_t my_orig_uid;
1067 gid_t my_orig_gid, my_new_gid1 = 0, my_new_gid2 = 0;
1068 ssize_t my_result;
1069 struct stat my_sb;
1070 gid_t my_groups[ NGROUPS_MAX ];
1071 char my_buffer[ 64 ];
1072 kern_return_t my_kr;
1073
1074 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1075 if(my_kr != KERN_SUCCESS){
1076 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1077 goto test_failed_exit;
1078 }
1079
1080 *my_pathp = 0x00;
1081 strcat( my_pathp, &g_target_path[0] );
1082 strcat( my_pathp, "/" );
1083
1084 /* create a test file */
1085 my_err = create_random_name( my_pathp, 1 );
1086 if ( my_err != 0 ) {
1087 goto test_failed_exit;
1088 }
1089
1090 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_link_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1091 if(my_kr != KERN_SUCCESS){
1092 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1093 goto test_failed_exit;
1094 }
1095
1096 *my_link_pathp = 0x00;
1097 strcat( my_link_pathp, &g_target_path[0] );
1098 strcat( my_link_pathp, "/" );
1099
1100 /* get a test file name for the link */
1101 my_err = create_random_name( my_link_pathp, 0 );
1102 if ( my_err != 0 ) {
1103 goto test_failed_exit;
1104 }
1105
1106 /* set up by getting a list of groups */
1107 my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
1108
1109 if ( my_group_count == -1 || my_group_count < 1 ) {
1110 printf( "getgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1111 goto test_failed_exit;
1112 }
1113
1114 my_err = stat( my_pathp, &my_sb );
1115 if ( my_err != 0 ) {
1116 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1117 goto test_failed_exit;
1118 }
1119
1120 /* now change group owner to something other than current value */
1121 my_orig_gid = my_sb.st_gid;
1122 my_orig_uid = my_sb.st_uid;
1123
1124 for ( i = 0; i < my_group_count; i++ ) {
1125 if ( my_orig_gid != my_groups[ i ] ) {
1126 if ( my_new_gid1 == 0 ) {
1127 my_new_gid1 = my_groups[ i ];
1128 }
1129 else {
1130 my_new_gid2 = my_groups[ i ];
1131 break;
1132 }
1133 }
1134 }
1135 if ( i >= my_group_count ) {
1136 printf( "not enough groups to choose from. st_gid is the same as current groups! \n" );
1137 goto test_failed_exit;
1138 }
1139
1140 my_err = chown( my_pathp, my_orig_uid, my_new_gid1 );
1141 if ( my_err != 0 ) {
1142 printf( "chown call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1143 goto test_failed_exit;
1144 }
1145
1146 /* make sure the group owner was changed */
1147 my_err = stat( my_pathp, &my_sb );
1148 if ( my_err != 0 ) {
1149 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1150 goto test_failed_exit;
1151 }
1152 if ( my_sb.st_gid == my_orig_gid ) {
1153 printf( "chown call failed. st_gid is not correct! \n" );
1154 goto test_failed_exit;
1155 }
1156
1157 /* change group owner back using fchown */
1158 my_fd = open( my_pathp, O_RDWR, 0 );
1159 if ( my_fd == -1 ) {
1160 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1161 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] );
1162 goto test_failed_exit;
1163 }
1164
1165 my_err = fchown( my_fd, my_orig_uid, my_new_gid2 );
1166 if ( my_err != 0 ) {
1167 printf( "fchown call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1168 goto test_failed_exit;
1169 }
1170
1171 /* make sure the group owner was changed back to the original value */
1172 my_err = stat( my_pathp, &my_sb );
1173 if ( my_err != 0 ) {
1174 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1175 goto test_failed_exit;
1176 }
1177 if ( my_sb.st_gid == my_new_gid1 ) {
1178 printf( "fchown call failed. st_gid is not correct! \n" );
1179 goto test_failed_exit;
1180 }
1181
1182 /* create a link file and test lchown */
1183 my_err = symlink( my_pathp, my_link_pathp );
1184 if ( my_err != 0 ) {
1185 printf( "symlink call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1186 goto test_failed_exit;
1187 }
1188
1189 my_err = lstat( my_link_pathp, &my_sb );
1190 if ( my_err != 0 ) {
1191 printf( "lstat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1192 goto test_failed_exit;
1193 }
1194
1195 /* now change group owner to something other than current value */
1196 my_orig_gid = my_sb.st_gid;
1197 my_orig_uid = my_sb.st_uid;
1198 my_err = lchown( my_link_pathp, my_orig_uid, my_new_gid1 );
1199 if ( my_err != 0 ) {
1200 printf( "lchown call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1201 goto test_failed_exit;
1202 }
1203
1204 /* make sure the group owner was changed to new value */
1205 my_err = lstat( my_link_pathp, &my_sb );
1206 if ( my_err != 0 ) {
1207 printf( "lstat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1208 goto test_failed_exit;
1209 }
1210 if ( my_sb.st_gid == my_new_gid2 ) {
1211 printf( "lchown call failed. st_gid is not correct! \n" );
1212 goto test_failed_exit;
1213 }
1214
1215 /* make sure we can read the symlink file */
1216 my_result = readlink( my_link_pathp, &my_buffer[0], sizeof(my_buffer) );
1217 if ( my_result == -1 ) {
1218 printf( "readlink call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1219 goto test_failed_exit;
1220 }
1221 /* make sure we read some data */
1222 if ( my_result < 1 ) {
1223 printf( "readlink failed to read any data. \n" );
1224 goto test_failed_exit;
1225 }
1226
1227 my_err = 0;
1228 goto test_passed_exit;
1229
1230 test_failed_exit:
1231 my_err = -1;
1232
1233 test_passed_exit:
1234 if ( my_fd != -1 )
1235 close( my_fd );
1236 if ( my_pathp != NULL ) {
1237 remove( my_pathp );
1238 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1239 }
1240 if ( my_link_pathp != NULL ) {
1241 unlink( my_link_pathp );
1242 vm_deallocate(mach_task_self(), (vm_address_t)my_link_pathp, PATH_MAX);
1243 }
1244 return( my_err );
1245 #else
1246 printf( "\t--> Test not designed for EMBEDDED TARGET\n" );
1247 return 0;
1248 #endif
1249 }
1250
1251 /* **************************************************************************************************************
1252 * Test fstatfs, getattrlist, getfsstat, statfs, getfsstat64, statfs64, fstatfs64 system calls.
1253 * **************************************************************************************************************
1254 */
1255
1256 #pragma pack(4)
1257 struct vol_attr_buf {
1258 u_int32_t length;
1259 off_t volume_size;
1260 u_int32_t io_blksize;
1261 };
1262 #pragma pack()
1263 typedef struct vol_attr_buf vol_attr_buf;
1264
1265 #define STATFS_TEST_PATH "/tmp"
1266
1267 int fs_stat_tests( void * the_argp )
1268 {
1269 int my_err, my_count, i;
1270 int my_buffer_size, my_buffer64_size;
1271 int my_fd = -1;
1272 int is_ufs = 0;
1273 long my_io_size;
1274 fsid_t my_fsid;
1275 struct attrlist my_attrlist;
1276 vol_attr_buf my_attr_buf;
1277 void * my_bufferp = NULL;
1278 struct statfs * my_statfsp;
1279 kern_return_t my_kr;
1280
1281 #if !TARGET_OS_EMBEDDED
1282 void * my_buffer64p = NULL;
1283 struct statfs64 * my_statfs64p;
1284
1285 my_buffer64_size = (sizeof(struct statfs64) * 10);
1286
1287 my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_buffer64p, my_buffer64_size, VM_FLAGS_ANYWHERE);
1288 if(my_kr != KERN_SUCCESS){
1289 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1290 goto test_failed_exit;
1291 }
1292
1293 #endif
1294 my_buffer_size = (sizeof(struct statfs) * 10);
1295
1296 my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_bufferp, my_buffer_size, VM_FLAGS_ANYWHERE);
1297 if(my_kr != KERN_SUCCESS){
1298 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1299 goto test_failed_exit;
1300 }
1301
1302 my_statfsp = (struct statfs *) my_bufferp;
1303 my_err = statfs( STATFS_TEST_PATH, my_statfsp );
1304 if ( my_err == -1 ) {
1305 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1306 goto test_failed_exit;
1307 }
1308 if ( memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ) {
1309 is_ufs = 1;
1310 }
1311
1312 my_count = getfsstat( (struct statfs *)my_bufferp, my_buffer_size, MNT_NOWAIT );
1313 if ( my_count == -1 ) {
1314 printf( "getfsstat call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1315 goto test_failed_exit;
1316 }
1317
1318 /* validate results */
1319 my_statfsp = (struct statfs *) my_bufferp;
1320 for ( i = 0; i < my_count; i++, my_statfsp++ ) {
1321 if ( memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
1322 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ||
1323 memcmp( &my_statfsp->f_fstypename[0], "devfs", 5 ) == 0 ||
1324 memcmp( &my_statfsp->f_fstypename[0], "volfs", 5 ) == 0 ) {
1325 /* found a valid entry */
1326 break;
1327 }
1328 }
1329 if ( i >= my_count ) {
1330 printf( "getfsstat call failed. could not find valid f_fstypename! \n" );
1331 goto test_failed_exit;
1332 }
1333
1334 #if !TARGET_OS_EMBEDDED
1335 /* now try statfs64 */
1336 my_statfs64p = (struct statfs64 *) my_buffer64p;
1337 my_err = statfs64( STATFS_TEST_PATH, my_statfs64p );
1338 if ( my_err == -1 ) {
1339 printf( "statfs64 call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1340 goto test_failed_exit;
1341 }
1342 if ( my_statfs64p->f_fsid.val[0] != my_statfsp->f_fsid.val[0] ||
1343 my_statfs64p->f_fsid.val[1] != my_statfsp->f_fsid.val[1] ) {
1344 printf( "statfs64 call failed. wrong f_fsid! \n" );
1345 goto test_failed_exit;
1346 }
1347
1348 my_count = getfsstat64( (struct statfs64 *)my_buffer64p, my_buffer64_size, MNT_NOWAIT );
1349 if ( my_count == -1 ) {
1350 printf( "getfsstat64 call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1351 goto test_failed_exit;
1352 }
1353
1354 /* validate results */
1355 my_statfs64p = (struct statfs64 *) my_buffer64p;
1356 for ( i = 0; i < my_count; i++, my_statfs64p++ ) {
1357 if ( memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 ||
1358 memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0 ||
1359 memcmp( &my_statfs64p->f_fstypename[0], "devfs", 5 ) == 0 ||
1360 memcmp( &my_statfs64p->f_fstypename[0], "volfs", 5 ) == 0 ) {
1361 /* found a valid entry */
1362 break;
1363 }
1364 }
1365 if ( i >= my_count ) {
1366 printf( "getfsstat64 call failed. could not find valid f_fstypename! \n" );
1367 goto test_failed_exit;
1368 }
1369 #endif
1370
1371 /* set up to validate results via multiple sources. we use getattrlist to get volume
1372 * related attributes to verify against results from fstatfs and statfs - but only if
1373 * we are not targeting ufs volume since it doesn't support getattr calls
1374 */
1375 if ( is_ufs == 0 ) {
1376 memset( &my_attrlist, 0, sizeof(my_attrlist) );
1377 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
1378 my_attrlist.volattr = (ATTR_VOL_SIZE | ATTR_VOL_IOBLOCKSIZE);
1379 my_err = getattrlist( "/", &my_attrlist, &my_attr_buf, sizeof(my_attr_buf), 0 );
1380 if ( my_err != 0 ) {
1381 printf( "getattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1382 goto test_failed_exit;
1383 }
1384 }
1385
1386 /* open to use as test file for fstatfs */
1387 my_fd = open( STATFS_TEST_PATH, O_RDONLY, 0 );
1388 if ( my_fd == -1 ) {
1389 printf( "open call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1390 goto test_failed_exit;
1391 }
1392
1393 #if !TARGET_OS_EMBEDDED
1394 /* testing fstatfs64 */
1395 my_statfs64p = (struct statfs64 *) my_buffer64p;
1396 my_err = fstatfs64( my_fd, my_statfs64p );
1397 if ( my_err == -1 ) {
1398 printf( "fstatfs64 call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1399 goto test_failed_exit;
1400 }
1401
1402 /* validate results - assumes we only boot from hfs or ufs */
1403 if ( !(memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 ||
1404 memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0) ) {
1405 printf( "fstatfs64 call failed. could not find valid f_fstypename! \n" );
1406 goto test_failed_exit;
1407 }
1408 #endif
1409
1410 /* testing fstatfs */
1411 my_statfsp = (struct statfs *) my_bufferp;
1412 my_err = fstatfs( my_fd, my_statfsp );
1413 if ( my_err == -1 ) {
1414 printf( "fstatfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1415 goto test_failed_exit;
1416 }
1417
1418 /* validate results */
1419 if ( !(memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 ||
1420 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0) ) {
1421 printf( "fstatfs call failed. could not find valid f_fstypename! \n" );
1422 goto test_failed_exit;
1423 }
1424 my_io_size = my_statfsp->f_iosize;
1425 my_fsid = my_statfsp->f_fsid;
1426 if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
1427 printf( "fstatfs and getattrlist results do not match for volume block size \n" );
1428 goto test_failed_exit;
1429 }
1430
1431 /* try again with statfs */
1432 my_err = statfs( STATFS_TEST_PATH , my_statfsp );
1433 if ( my_err == -1 ) {
1434 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1435 goto test_failed_exit;
1436 }
1437
1438 /* validate results */
1439 if ( my_io_size != my_statfsp->f_iosize || my_fsid.val[0] != my_statfsp->f_fsid.val[0] ||
1440 my_fsid.val[1] != my_statfsp->f_fsid.val[1] ) {
1441 printf( "statfs call failed. wrong f_iosize or f_fsid! \n" );
1442 goto test_failed_exit;
1443 }
1444 if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) {
1445 printf( "statfs and getattrlist results do not match for volume block size \n" );
1446 goto test_failed_exit;
1447 }
1448
1449 my_err = 0;
1450 goto test_passed_exit;
1451
1452 test_failed_exit:
1453 my_err = -1;
1454
1455 test_passed_exit:
1456 if ( my_fd != -1 )
1457 close( my_fd );
1458 if ( my_bufferp != NULL ) {
1459 vm_deallocate(mach_task_self(), (vm_address_t)my_bufferp, my_buffer_size);
1460 }
1461 #if !TARGET_OS_EMBEDDED
1462 if ( my_buffer64p != NULL ) {
1463 vm_deallocate(mach_task_self(), (vm_address_t)my_buffer64p, my_buffer64_size);
1464 }
1465 #endif
1466
1467 return( my_err );
1468 }
1469
1470 /* **************************************************************************************************************
1471 * Test getpid, getppid, and pipe system calls.
1472 * **************************************************************************************************************
1473 */
1474 int getpid_getppid_pipe_test( void * the_argp )
1475 {
1476 int my_err, my_status;
1477 pid_t my_pid, my_wait_pid;
1478 ssize_t my_count;
1479 int my_fildes[2] = {-1, -1};
1480 off_t my_current_offset;
1481 char my_pid_string[64];
1482
1483 my_err = pipe( &my_fildes[0] );
1484 if ( my_err != 0 ) {
1485 printf( "pipe call failed. got errno %d - %s. \n", errno, strerror( errno ) );
1486 goto test_failed_exit;
1487 }
1488
1489 /* make sure we can't seek on a pipe */
1490 my_current_offset = lseek( my_fildes[0], 0, SEEK_CUR );
1491 if ( my_current_offset != -1 ) {
1492 printf( "lseek on pipe should fail but did not \n" );
1493 goto test_failed_exit;
1494 }
1495
1496 /* fork here and use pipe to communicate */
1497 my_pid = fork( );
1498 if ( my_pid == -1 ) {
1499 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
1500 goto test_failed_exit;
1501 }
1502 else if ( my_pid == 0 ) {
1503 /* child process */
1504 unsigned long my_ppid;
1505 char my_buffer[64];
1506
1507 close( my_fildes[1] ); /* close write end of pipe */
1508 my_fildes[1] = -1;
1509
1510 /* get the parent's pid using getppid and from the parent (using getpid in porent) */
1511 my_count = read( my_fildes[0], &my_buffer[0], sizeof(my_buffer) );
1512 if ( my_count == -1 ) {
1513 printf( "read from pipe failed. got errno %d - %s. \n", errno, strerror( errno ) );
1514 exit(-1);
1515 }
1516
1517 /* parent wrote (to our pipe) its pid as character string */
1518 my_ppid = strtoul( &my_buffer[0], NULL, 10 );
1519 if ( my_ppid == 0 ) {
1520 printf( "strtoul failed. got errno %d - %s. \n", errno, strerror( errno ) );
1521 exit(-1);
1522 }
1523
1524 if ( getppid( ) != my_ppid ) {
1525 printf( "getppid failed. pid we got from parent does not match getppid result. \n" );
1526 exit(-1);
1527 }
1528 exit(0);
1529 }
1530
1531 /* parent process - get our pid using getpid and send it to child for verification */
1532 close( my_fildes[0] ); /* close read end of pipe */
1533 my_fildes[0] = -1;
1534
1535 sprintf( &my_pid_string[0], "%d\n", getpid( ) );
1536
1537 my_count = write( my_fildes[1], &my_pid_string[0], sizeof(my_pid_string) );
1538 if ( my_count == -1 ) {
1539 printf( "write to pipe failed. got errno %d - %s. \n", errno, strerror( errno ) );
1540 goto test_failed_exit;
1541 }
1542
1543 /* wait for child to exit */
1544 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
1545 if ( my_wait_pid == -1 ) {
1546 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
1547 goto test_failed_exit;
1548 }
1549
1550 /* wait4 should return our child's pid when it exits */
1551 if ( my_wait_pid != my_pid ) {
1552 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
1553 goto test_failed_exit;
1554 }
1555
1556 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
1557 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
1558 goto test_failed_exit;
1559 }
1560
1561 my_err = 0;
1562 goto test_passed_exit;
1563
1564 test_failed_exit:
1565 my_err = -1;
1566
1567 test_passed_exit:
1568 if ( my_fildes[0] != -1 )
1569 close( my_fildes[0] );
1570 if ( my_fildes[1] != -1 )
1571 close( my_fildes[1] );
1572 return( my_err );
1573 }
1574
1575
1576 /* **************************************************************************************************************
1577 * Test getauid, gettid, getuid, geteuid, issetugid, setaudit_addr, seteuid, settid, settid_with_pid, setuid system calls.
1578 * **************************************************************************************************************
1579 */
1580 int uid_tests( void * the_argp )
1581 {
1582 int my_err, my_status;
1583 pid_t my_pid, my_wait_pid;
1584
1585 if ( g_skip_setuid_tests != 0 ) {
1586 printf("\t skipping this test \n");
1587 my_err = 0;
1588 goto test_passed_exit;
1589 }
1590
1591 /* test issetugid - should return 1 when not root and 0 when root
1592 * Figuring out setugid will not work in single-user mode; skip
1593 * this test in that case.
1594 */
1595 if (!g_is_single_user) {
1596 my_err = issetugid( );
1597 if ( getuid( ) == 0 ) {
1598 if ( my_err == 1 ) {
1599 printf( "issetugid should return false \n" );
1600 goto test_failed_exit;
1601 }
1602 }
1603 else {
1604 if ( my_err == 0 ) {
1605 printf( "issetugid should return true \n" );
1606 goto test_failed_exit;
1607 }
1608 }
1609 }
1610
1611 /*
1612 * fork here and do the setuid work in the child
1613 */
1614 my_pid = fork( );
1615 if ( my_pid == -1 ) {
1616 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
1617 goto test_failed_exit;
1618 }
1619 else if ( my_pid == 0 ) {
1620 /*
1621 * child process
1622 */
1623 uid_t my_ruid, my_euid;
1624 uid_t my_uid, my_temp_uid;
1625 gid_t my_gid, my_temp_gid;
1626 auditinfo_addr_t my_aia;
1627
1628 my_ruid = getuid( );
1629 my_euid = geteuid( );
1630 if ( my_ruid == my_euid ) {
1631 exit( 0 );
1632 }
1633
1634 /* Test getauid, gettid, setaudit_addr, settid, settid_with_pid */
1635 /* get our current uid and gid for comparison later */
1636 my_uid = getuid( );
1637 my_gid = getgid( );
1638
1639 my_err = syscall( SYS_settid, 4444, 5555 );
1640 //my_err = settid( 4444, 5555 );
1641 if (my_err != 0) {
1642 printf( "settid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1643 exit( -1 );
1644 }
1645
1646 my_err = syscall( SYS_gettid, &my_temp_uid, &my_temp_gid );
1647 //my_err = gettid( &my_temp_uid, &my_temp_gid );
1648 if (my_err != 0) {
1649 printf( "gettid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1650 exit( -1 );
1651 }
1652 if (my_temp_uid != 4444) {
1653 printf("get / settid test failed - wrong uid was set - %d \n", my_temp_uid);
1654 exit( -1 );
1655 }
1656 if (my_temp_gid != 5555) {
1657 printf("get / settid test failed - wrong gid was set - %d \n", my_temp_gid);
1658 exit( -1 );
1659 }
1660
1661 /* resume original identity */
1662 my_err = syscall( SYS_settid, KAUTH_UID_NONE, KAUTH_GID_NONE );
1663 //my_err = settid( KAUTH_UID_NONE, KAUTH_GID_NONE );
1664 if (my_err != 0) {
1665 printf( "settid revert - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1666 exit( -1 );
1667 }
1668
1669 /* values should be returned to original settings */
1670 my_temp_uid = getuid( );
1671 if (my_temp_uid == 4444) {
1672 printf("test failed - wrong uid was set - %d \n", my_temp_uid);
1673 exit( -1 );
1674 }
1675 my_temp_gid = getgid( );
1676 if (my_temp_gid == 5555) {
1677 printf("test failed - wrong gid was set - %d \n", my_temp_gid);
1678 exit( -1 );
1679 }
1680
1681 /*
1682 * Assume the identity of our parent.
1683 */
1684 my_err = syscall( SYS_settid_with_pid, getppid( ), 1 );
1685 //my_err = settid_with_pid, my_target_pid, 1 );
1686 if (my_err != 0) {
1687 printf( "settid_with_pid assume - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1688 exit( -1 );
1689 }
1690
1691 /*
1692 * Resume our identity.
1693 */
1694 my_err = syscall( SYS_settid_with_pid, 0, 0 );
1695 //my_err = settid_with_pid( my_target_pid, 0 );
1696 if (my_err != 0) {
1697 printf( "settid_with_pid resume - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1698 exit( -1 );
1699 }
1700
1701 /*
1702 * test to make sure setaudit_addr doesn't cause audit info to get lost from
1703 * the credential.
1704 */
1705 bzero( &my_aia, sizeof(my_aia) );
1706 my_aia.ai_auid = 442344;
1707 my_aia.ai_asid = AU_ASSIGN_ASID;
1708 my_aia.ai_termid.at_type = AU_IPv4;
1709 my_err = setaudit_addr( &my_aia, sizeof(my_aia) );
1710 if (my_err != 0) {
1711 printf( "setaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1712 exit( -1 );
1713 }
1714
1715 my_aia.ai_auid = 0;
1716 my_err = getaudit_addr( &my_aia, sizeof(my_aia) );
1717 if (my_err != 0) {
1718 printf( "getaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) );
1719 exit( -1 );
1720 }
1721 //printf("new audit ID is %d \n", my_aia.ai_auid);
1722
1723 if (my_aia.ai_auid != 442344) {
1724 printf("test failed - wrong audit ID was set - %d \n", my_aia.ai_auid);
1725 exit( -1 );
1726 }
1727
1728 /* change real uid and effective uid to current euid */
1729 my_err = setuid( my_euid );
1730 if ( my_err == -1 ) {
1731 printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1732 exit( -1 );
1733 }
1734 if ( getuid( ) != my_euid ) {
1735 printf( "setuid call failed to set the real uid \n" );
1736 exit( -1 );
1737 }
1738
1739 /* change effective uid to current euid - really a NOP */
1740 my_err = seteuid( my_euid );
1741 if ( my_err == -1 ) {
1742 printf( "seteuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1743 exit( -1 );
1744 }
1745 if ( geteuid( ) != my_euid ) {
1746 printf( "seteuid call failed to set the original euid \n" );
1747 exit( -1 );
1748 }
1749
1750 /* change real uid and effective uid to original real uid */
1751 my_err = setuid( my_ruid );
1752 if ( my_err == -1 ) {
1753 printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1754 exit( -1 );
1755 }
1756 if ( getuid( ) != my_ruid ) {
1757 printf( "setuid call failed to set the real uid \n" );
1758 exit( -1 );
1759 }
1760
1761 exit(0);
1762 }
1763
1764 /*
1765 * parent process -
1766 * wait for child to exit
1767 */
1768 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
1769 if ( my_wait_pid == -1 ) {
1770 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
1771 goto test_failed_exit;
1772 }
1773
1774 /* wait4 should return our child's pid when it exits */
1775 if ( my_wait_pid != my_pid ) {
1776 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
1777 goto test_failed_exit;
1778 }
1779
1780 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
1781 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
1782 goto test_failed_exit;
1783 }
1784
1785 my_err = 0;
1786 goto test_passed_exit;
1787
1788 test_failed_exit:
1789 my_err = -1;
1790
1791 test_passed_exit:
1792 return( my_err );
1793 }
1794
1795 /* **************************************************************************************************************
1796 * Test mknod, sync system calls.
1797 * **************************************************************************************************************
1798 */
1799 int mknod_sync_test( void * the_argp )
1800 {
1801 int my_err;
1802 char * my_pathp = NULL;
1803 kern_return_t my_kr;
1804
1805 if ( g_skip_setuid_tests != 0 ) {
1806 printf("\t skipping this test \n");
1807 my_err = 0;
1808 goto test_passed_exit;
1809 }
1810
1811 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1812 if(my_kr != KERN_SUCCESS){
1813 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1814 goto test_failed_exit;
1815 }
1816
1817 *my_pathp = 0x00;
1818 strcat( my_pathp, "/dev/" );
1819
1820 /* get a unique name for our test file */
1821 my_err = create_random_name( my_pathp, 0 );
1822 if ( my_err != 0 ) {
1823 goto test_failed_exit;
1824 }
1825
1826 my_err = mknod( my_pathp, (S_IFCHR | S_IRWXU), 0 );
1827 if ( my_err == -1 ) {
1828 printf( "mknod failed with errno %d - %s \n", errno, strerror( errno ) );
1829 printf( "path \"%s\" \n", my_pathp );
1830 goto test_failed_exit;
1831 }
1832
1833 /* not really sure what to do with sync call test */
1834 sync( );
1835 my_err = 0;
1836 goto test_passed_exit;
1837
1838 test_failed_exit:
1839 my_err = -1;
1840
1841 test_passed_exit:
1842 if ( my_pathp != NULL ) {
1843 remove( my_pathp );
1844 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1845 }
1846 return( my_err );
1847 }
1848
1849 /* **************************************************************************************************************
1850 * Test chflags, fchflags system calls.
1851 * **************************************************************************************************************
1852 */
1853 int chflags_fchflags_test( void * the_argp )
1854 {
1855 int my_err;
1856 int my_fd = -1;
1857 u_int my_flags;
1858 char * my_pathp = NULL;
1859 struct stat my_sb;
1860 kern_return_t my_kr;
1861
1862 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
1863 if(my_kr != KERN_SUCCESS){
1864 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
1865 goto test_failed_exit;
1866 }
1867
1868 *my_pathp = 0x00;
1869 strcat( my_pathp, &g_target_path[0] );
1870 strcat( my_pathp, "/" );
1871
1872 /* create a test file */
1873 my_err = create_random_name( my_pathp, 1 );
1874 if ( my_err != 0 ) {
1875 goto test_failed_exit;
1876 }
1877
1878 /* make test file unchangable */
1879 my_err = stat( my_pathp, &my_sb );
1880 if ( my_err != 0 ) {
1881 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1882 goto test_failed_exit;
1883 }
1884
1885 my_flags = (my_sb.st_flags | UF_IMMUTABLE);
1886 my_err = chflags( my_pathp, my_flags );
1887 if ( my_err != 0 ) {
1888 printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1889 goto test_failed_exit;
1890 }
1891
1892 /* should fail with EPERM since we cannot change the file now */
1893 my_fd = open( my_pathp, O_RDWR, 0 );
1894 if ( my_fd == -1 && errno != EPERM ) {
1895 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1896 printf( "open failed with wrong error - should be EPERM \n" );
1897 goto test_failed_exit;
1898 }
1899
1900 /* this open should work OK */
1901 my_fd = open( my_pathp, O_RDONLY, 0 );
1902 if ( my_fd == -1 ) {
1903 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1904 goto test_failed_exit;
1905 }
1906
1907 my_err = stat( my_pathp, &my_sb );
1908 if ( my_err != 0 ) {
1909 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1910 goto test_failed_exit;
1911 }
1912
1913 my_flags = (my_sb.st_flags & ~UF_IMMUTABLE);
1914 my_err = fchflags( my_fd, my_flags );
1915 if ( my_err != 0 ) {
1916 printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1917 goto test_failed_exit;
1918 }
1919
1920 close( my_fd );
1921 my_fd = -1;
1922
1923 /* should now work */
1924 my_fd = open( my_pathp, O_RDWR, 0 );
1925 if ( my_fd == -1 ) {
1926 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
1927 goto test_failed_exit;
1928 }
1929
1930 my_err = 0;
1931 goto test_passed_exit;
1932
1933 test_failed_exit:
1934 my_err = -1;
1935
1936 test_passed_exit:
1937 if ( my_fd != -1 )
1938 close( my_fd );
1939 if ( my_pathp != NULL ) {
1940 remove( my_pathp );
1941 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
1942 }
1943 return( my_err );
1944 }
1945
1946
1947 /* **************************************************************************************************************
1948 * Test kill, vfork, execve system calls.
1949 * **************************************************************************************************************
1950 */
1951 /* There are many new exec() situations to test now that 64-bit is in. These extra tests are in response to
1952 * rdar://4606399 and rdar://4607285. It should cover every permutation of the following variables.
1953 *
1954 * - Current Process "Bitness": 64 or 32
1955 * - exec()'ed process "bitness": 64 or 32
1956 * (if 64 bit, size of page zero:) (4GB or 4KB)
1957 * - Parent Process "Bitness": 64 or 32
1958
1959 * Test to make sure certain inheritance properties of fork()'ed children
1960 * are correctly set.
1961 * 1. 64 bit process forking() 64-bit child, child execing() 64-bit file (4GB pagezero)
1962 * 2. 64 bit process forking() 64-bit child, child execing() 64-bit file (4KB pagezero)
1963 * 3. 64 bit process forking() 64-bit child, child execing() 32-bit file
1964 * 4. 32 bit process forking() 32-bit child, child execing() 32-bit file
1965 * 5. 32 bit process forking() 32-bit child, child execing() 64 bit file (4GB pagezero)
1966 * 6. 32 bit process forking() 32-bit child, child execing() 64 bit file (4KB pagezero)
1967 *
1968 */
1969
1970
1971 int execve_kill_vfork_test( void * the_argp )
1972 {
1973 int my_err, my_status;
1974 pid_t my_pid, my_wait_pid;
1975 char * errmsg = NULL;
1976 char * argvs[2] = {"", NULL};
1977 int bits = get_bits(); /* Gets actual processor bit-ness. */
1978
1979 if (bits != 32 && bits != 64) {
1980 printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits());
1981 return(-1);
1982 }
1983
1984 if (get_architecture() == -1) {
1985 errmsg = "get_architecture() could not determine the CPU architecture.\n";
1986 goto test_failed_exit;
1987 }
1988
1989 if (get_architecture() == INTEL) {
1990 struct stat sb;
1991
1992 if (bits == 64 && sizeof(long) == 8) {
1993 /*
1994 * Running on x86_64 hardware and running in 64-bit mode.
1995 * Check cases 1, 2, 3 and fork a child to check 4, 5, 6.
1996 */
1997 errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4G pagezero.\n";
1998 argvs[0] = "sleep-x86_64-4G";
1999 if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 1)) goto test_failed_exit;
2000
2001 errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4K Pagezero.\n";
2002 argvs[0] = "sleep-x86_64-4K";
2003 if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 1)) goto test_failed_exit;
2004
2005 errmsg = "execve failed: from x64_64 forking and exec()ing 32-bit i386 process.\n";
2006 argvs[0] = "sleep-i386";
2007 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) goto test_failed_exit;
2008
2009 /* Fork off a helper process and load a 32-bit program in it to test 32->64 bit exec(). */
2010 errmsg = "execve failed to exec the helper process.\n";
2011 argvs[0] = "launch-i386";
2012 if (do_execve_test("helpers/launch-i386", argvs, NULL, 1) != 0) goto test_failed_exit;
2013
2014 /* Test posix_spawn for i386, x86_64 (should succeed) */
2015 errmsg = NULL;
2016 if (do_spawn_test(CPU_TYPE_I386, 0))
2017 goto test_failed_exit;
2018 if (do_spawn_test(CPU_TYPE_X86_64, 0))
2019 goto test_failed_exit;
2020 }
2021 else if (bits == 64 && sizeof(long) == 4) {
2022 /*
2023 * Running on x86_64 hardware, but actually running in 32-bit mode.
2024 * Check cases 4, 5, 6 and fork a child to check 1, 2, 3.
2025 */
2026 errmsg = "execve failed: from i386 forking and exec()ing i386 process.\n";
2027 argvs[0] = "sleep-i386";
2028 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 0)) goto test_failed_exit;
2029
2030 errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4G pagezero.\n";
2031 argvs[0] = "sleep-x86_64-4G";
2032 if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 0)) goto test_failed_exit;
2033
2034 errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4K pagezero.\n";
2035 argvs[0] = "sleep-x86_64-4K";
2036 if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 0)) goto test_failed_exit;
2037
2038 /* Fork off a helper process and load a 64-bit program in it to test 64->32 bit exec(). */
2039 errmsg = "execve failed to exec the helper process.\n";
2040 argvs[0] = "launch-x86_64";
2041 if (do_execve_test("helpers/launch-x86_64", argvs, NULL, 1) != 0) goto test_failed_exit;
2042
2043 /* Test posix_spawn for i386, x86_64 (should succeed) */
2044 errmsg = NULL;
2045 if (do_spawn_test(CPU_TYPE_I386, 0))
2046 goto test_failed_exit;
2047 if (do_spawn_test(CPU_TYPE_X86_64, 0))
2048 goto test_failed_exit;
2049 }
2050 else if (bits == 32) {
2051 /* Running on i386 hardware. Check cases 4. */
2052 errmsg = "execve failed: from i386 forking and exec()ing 32-bit i386 process.\n";
2053 argvs[0] = "sleep-i386";
2054 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) goto test_failed_exit;
2055
2056 /* Test posix_spawn for x86_64 (should fail), i386 (should succeed) */
2057 errmsg = NULL;
2058 if (do_spawn_test(CPU_TYPE_X86_64, 1))
2059 goto test_failed_exit;
2060 if (do_spawn_test(CPU_TYPE_I386, 0))
2061 goto test_failed_exit;
2062 }
2063 }else if(get_architecture() == ARM) {
2064 if (bits == 32) {
2065
2066 /* Running on arm hardware. Check cases 2. */
2067 errmsg = "execve failed: from arm forking and exec()ing 32-bit arm process.\n";
2068 argvs[0] = "sleep-arm";
2069 if (do_execve_test("helpers/sleep-arm", argvs, NULL, 1))
2070 goto test_failed_exit;
2071
2072 /* Test posix_spawn for arm (should succeed) */
2073 errmsg = NULL;
2074 if (do_spawn_test(CPU_TYPE_ARM, 0))
2075 goto test_failed_exit;
2076 }
2077 }
2078 else {
2079 /* Just in case someone decides we need more architectures in the future */
2080 printf("get_architecture() returned unknown architecture");
2081 return(-1);
2082 }
2083
2084 return 0;
2085
2086 test_failed_exit:
2087 if (errmsg)
2088 printf("%s", errmsg);
2089 return -1;
2090 }
2091
2092
2093 /* **************************************************************************************************************
2094 * Test getegid, getgid, getgroups, setegid, setgid, setgroups system calls.
2095 * **************************************************************************************************************
2096 */
2097 int groups_test( void * the_argp )
2098 {
2099 #if !TARGET_OS_EMBEDDED
2100 int my_err, i;
2101 int my_group_count, my_orig_group_count;
2102 gid_t my_real_gid;
2103 gid_t my_effective_gid;
2104 gid_t my_removed_gid;
2105 gid_t my_new_gid;
2106 gid_t my_groups[ NGROUPS_MAX ];
2107
2108 if ( g_skip_setuid_tests != 0 ) {
2109 printf("\t skipping this test \n");
2110 my_err = 0;
2111 goto test_passed_exit;
2112 }
2113
2114 my_real_gid = getgid( );
2115 my_effective_gid = getegid( );
2116
2117 /* start by getting list of groups the current user belongs to */
2118 my_orig_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
2119
2120 if ( my_orig_group_count == -1 || my_orig_group_count < 1 ) {
2121 printf( "getgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2122 goto test_failed_exit;
2123 }
2124
2125 /* make sure real and effective gids are correct */
2126 for ( i = 0; i < my_orig_group_count; i++ ) {
2127 if ( my_groups[i] == my_real_gid )
2128 break;
2129 }
2130 if ( i >= my_orig_group_count ) {
2131 printf( "getgid or getgroups call failed. could not find real gid in list of groups. \n" );
2132 goto test_failed_exit;
2133 }
2134 for ( i = 0; i < my_orig_group_count; i++ ) {
2135 if ( my_groups[i] == my_effective_gid )
2136 break;
2137 }
2138 if ( i >= my_orig_group_count ) {
2139 printf( "getegid or getgroups call failed. could not find effective gid in list of groups. \n" );
2140 goto test_failed_exit;
2141 }
2142
2143 /* remove the last group */
2144 my_removed_gid = my_groups[ (my_orig_group_count - 1) ];
2145 my_err = setgroups( (my_orig_group_count - 1), &my_groups[0] );
2146 if ( my_err == -1 ) {
2147 printf( "setgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2148 goto test_failed_exit;
2149 }
2150
2151 my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
2152
2153 if ( my_group_count == -1 || my_group_count < 1 ) {
2154 printf( "getgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2155 goto test_failed_exit;
2156 }
2157
2158 /* make sure setgroups dropped one */
2159 if ( my_orig_group_count <= my_group_count ) {
2160 printf( "setgroups call failed. current group count is too high. \n" );
2161 goto test_failed_exit;
2162 }
2163
2164 /* now put removed gid back */
2165 my_groups[ (my_orig_group_count - 1) ] = my_removed_gid;
2166 my_err = setgroups( my_orig_group_count, &my_groups[0] );
2167 if ( my_err == -1 ) {
2168 printf( "setgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2169 goto test_failed_exit;
2170 }
2171
2172 /* find a group to change real and effective gid to then do it */
2173 my_new_gid = -1;
2174 for ( i = 0; i < my_orig_group_count; i++ ) {
2175 if ( my_groups[i] == my_effective_gid || my_groups[i] == my_real_gid )
2176 continue;
2177 my_new_gid = my_groups[i];
2178 }
2179
2180 if ( my_new_gid == -1 ) {
2181 printf( "could not find a gid to switch to. \n" );
2182 goto test_failed_exit;
2183 }
2184
2185 /* test setegid */
2186 my_err = setegid( my_new_gid );
2187 if ( my_err == -1 ) {
2188 printf( "setegid call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2189 goto test_failed_exit;
2190 }
2191 /* verify it changed */
2192 if ( getegid( ) != my_new_gid ) {
2193 printf( "setegid failed to change the effective gid. \n" );
2194 goto test_failed_exit;
2195 }
2196 /* change it back to original value */
2197 my_err = setegid( my_effective_gid );
2198 if ( my_err == -1 ) {
2199 printf( "setegid call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2200 goto test_failed_exit;
2201 }
2202
2203 /* test setgid */
2204 my_err = setgid( my_new_gid );
2205 if ( my_err == -1 ) {
2206 printf( "setgid call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2207 goto test_failed_exit;
2208 }
2209 /* verify it changed */
2210 if ( getgid( ) != my_new_gid ) {
2211 printf( "setgid failed to change the real gid. \n" );
2212 goto test_failed_exit;
2213 }
2214 /* change it back to original value */
2215 my_err = setgid( my_real_gid );
2216 if ( my_err == -1 ) {
2217 printf( "setegid call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2218 goto test_failed_exit;
2219 }
2220
2221 my_err = 0;
2222 goto test_passed_exit;
2223
2224 test_failed_exit:
2225 my_err = -1;
2226
2227 test_passed_exit:
2228 return( my_err );
2229 #else
2230 printf( "\t--> Test not designed for EMBEDDED TARGET\n" );
2231 return 0;
2232 #endif
2233 }
2234
2235
2236 /* **************************************************************************************************************
2237 * Test dup, dup2, getdtablesize system calls.
2238 * **************************************************************************************************************
2239 */
2240 int dup_test( void * the_argp )
2241 {
2242 int my_err;
2243 int my_fd = -1;
2244 int my_newfd = -1;
2245 int my_table_size, my_loop_counter = 0;
2246 char * my_pathp = NULL;
2247 ssize_t my_count;
2248 char my_buffer[64];
2249 kern_return_t my_kr;
2250
2251 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2252 if(my_kr != KERN_SUCCESS){
2253 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2254 goto test_failed_exit;
2255 }
2256
2257 *my_pathp = 0x00;
2258 strcat( my_pathp, &g_target_path[0] );
2259 strcat( my_pathp, "/" );
2260
2261 /* create a test file */
2262 my_err = create_random_name( my_pathp, 1 );
2263 if ( my_err != 0 ) {
2264 goto test_failed_exit;
2265 }
2266
2267 /* test dup, dup2, getdtablesize */
2268 my_table_size = getdtablesize( );
2269 if ( my_table_size < 20 ) {
2270 printf( "getdtablesize should return at least 20, returned %d \n", my_table_size );
2271 goto test_failed_exit;
2272 }
2273
2274 my_fd = open( my_pathp, O_RDWR, 0 );
2275 if ( my_fd == -1 ) {
2276 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2277 goto test_failed_exit;
2278 }
2279
2280 my_newfd = dup( my_fd );
2281 if ( my_newfd == -1 ) {
2282 printf( "dup call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2283 goto test_failed_exit;
2284 }
2285
2286 redo:
2287 /* now write somne data to the orginal and new fd */
2288 /* make sure test file is empty */
2289 my_err = ftruncate( my_fd, 0 );
2290 if ( my_err == -1 ) {
2291 printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2292 goto test_failed_exit;
2293 }
2294
2295 lseek( my_fd, 0, SEEK_SET );
2296 my_count = write( my_fd, "aa", 2 );
2297 if ( my_count == -1 ) {
2298 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2299 goto test_failed_exit;
2300 }
2301
2302 my_count = write( my_newfd, "xx", 2 );
2303 if ( my_count == -1 ) {
2304 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
2305 goto test_failed_exit;
2306 }
2307
2308 /* now read it back and make sure data is correct */
2309 lseek( my_fd, 0, SEEK_SET );
2310 my_count = read( my_fd, &my_buffer[0], sizeof(my_buffer) );
2311 if ( my_count == -1 ) {
2312 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2313 goto test_failed_exit;
2314 }
2315 if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) {
2316 printf( "wrong data in test file. \n" );
2317 goto test_failed_exit;
2318 }
2319
2320 bzero( &my_buffer[0], sizeof(my_buffer) );
2321 lseek( my_newfd, 0, SEEK_SET );
2322 my_count = read( my_newfd, &my_buffer[0], sizeof(my_buffer) );
2323 if ( my_count == -1 ) {
2324 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2325 goto test_failed_exit;
2326 }
2327 if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) {
2328 printf( "wrong data in test file. \n" );
2329 goto test_failed_exit;
2330 }
2331
2332 /* we do the above tests twice - once for dup and once for dup2 */
2333 if ( my_loop_counter < 1 ) {
2334 my_loop_counter++;
2335 close( my_newfd );
2336
2337 my_err = dup2( my_fd, my_newfd );
2338 if ( my_err == -1 ) {
2339 printf( "dup2 call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2340 goto test_failed_exit;
2341 }
2342
2343 goto redo;
2344 }
2345
2346 my_err = 0;
2347 goto test_passed_exit;
2348
2349 test_failed_exit:
2350 my_err = -1;
2351
2352 test_passed_exit:
2353 if ( my_fd != -1 )
2354 close( my_fd );
2355 if ( my_newfd != -1 )
2356 close( my_newfd );
2357 if ( my_pathp != NULL ) {
2358 remove( my_pathp );
2359 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2360 }
2361 return( my_err );
2362 }
2363
2364
2365 /* **************************************************************************************************************
2366 * Test getrusage system call.
2367 * **************************************************************************************************************
2368 */
2369 int getrusage_test( void * the_argp )
2370 {
2371 int my_err;
2372 struct rusage my_rusage;
2373
2374 my_err = getrusage( RUSAGE_SELF, &my_rusage );
2375 if ( my_err == -1 ) {
2376 printf( "getrusage failed with error %d - \"%s\" \n", errno, strerror( errno) );
2377 goto test_failed_exit;
2378 }
2379
2380 /* do a sanity check on the getrusage results */
2381 if ( my_rusage.ru_msgrcv > 1000 || my_rusage.ru_msgrcv < 0 ) {
2382 printf( "getrusage seems to report wrong data - ru_msgrcv looks odd. \n" );
2383 goto test_failed_exit;
2384 }
2385 if ( my_rusage.ru_nsignals > 1000 || my_rusage.ru_nsignals < 0 ) {
2386 printf( "getrusage seems to report wrong data - ru_nsignals looks odd. \n" );
2387 goto test_failed_exit;
2388 }
2389
2390 my_err = 0;
2391 goto test_passed_exit;
2392
2393 test_failed_exit:
2394 my_err = -1;
2395
2396 test_passed_exit:
2397 return( my_err );
2398 }
2399
2400 /* **************************************************************************************************************
2401 * Test getitimer, setitimer, sigaction, sigpending, sigprocmask, sigsuspend, sigwait system calls.
2402 * **************************************************************************************************************
2403 */
2404
2405 int alarm_global = 0;
2406 void test_alarm_handler( int the_arg );
2407 void test_alarm_handler( int the_arg )
2408 {
2409 alarm_global = 4;
2410 //printf( "test_alarm_handler - got here \n" );
2411 if ( the_arg == 0 ) {
2412 }
2413 return;
2414 }
2415
2416 void test_signal_handler( int the_arg );
2417 void test_signal_handler( int the_arg )
2418 {
2419 //printf( "test_signal_handler - got here \n" );
2420 if ( the_arg == 0 ) {
2421 }
2422 return;
2423 }
2424
2425 int signals_test( void * the_argp )
2426 {
2427 int my_err, my_status;
2428 int my_fd = -1;
2429 char * my_pathp = NULL;
2430 pid_t my_pid, my_wait_pid;
2431 kern_return_t my_kr;
2432
2433 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2434 if(my_kr != KERN_SUCCESS){
2435 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2436 goto test_failed_exit;
2437 }
2438
2439 *my_pathp = 0x00;
2440 strcat( my_pathp, &g_target_path[0] );
2441 strcat( my_pathp, "/" );
2442
2443 /* create a test file */
2444 my_err = create_random_name( my_pathp, 1 );
2445 if ( my_err != 0 ) {
2446 goto test_failed_exit;
2447 }
2448
2449 /*
2450 * spin off a child process that we will use for signal related testing.
2451 */
2452 my_pid = fork( );
2453 if ( my_pid == -1 ) {
2454 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2455 goto test_failed_exit;
2456 }
2457 if ( my_pid == 0 ) {
2458 /*
2459 * child process - test signal related system calls.
2460 */
2461 //int my_counter;
2462 int my_signal;
2463 sigset_t my_sigset;
2464 struct sigaction my_sigaction;
2465 #ifdef MAC_OS_X_VERSION_10_5
2466 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
2467 /* If this is Leopard. To allow compiling for Inca x86_64 this definition cannot
2468 * be included. But it is needed to compile on Leopard.
2469 */
2470 struct __darwin_sigaltstack my_sigaltstack;
2471 #endif
2472 #else
2473 struct sigaltstack my_sigaltstack;
2474 #endif
2475 struct itimerval my_timer;
2476
2477
2478 /* test getting the current signal stack context */
2479 my_err = sigaltstack( NULL, &my_sigaltstack );
2480 if ( my_err == -1 ) {
2481 printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) );
2482 exit( -1 );
2483 }
2484 if ( (my_sigaltstack.ss_flags & SS_DISABLE) == 0 ) {
2485 printf( "sigaction must have failed - SS_DISABLE is cleared \n" );
2486 exit( -1 );
2487 }
2488
2489 /* set up to catch SIGUSR1 */
2490 my_sigaction.sa_handler = test_signal_handler;
2491 my_sigaction.sa_flags = SA_RESTART;
2492 my_sigaction.sa_mask = 0;
2493
2494 my_err = sigaction( SIGUSR1, &my_sigaction, NULL );
2495 if ( my_err == -1 ) {
2496 printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) );
2497 exit( -1 );
2498 }
2499
2500 /* now suspend until signal SIGUSR1 is sent */
2501 sigemptyset( &my_sigset );
2502 my_err = sigsuspend( &my_sigset );
2503 if ( my_err == -1 ) {
2504 if ( errno != EINTR ) {
2505 printf( "sigsuspend should have returned with errno EINTR \n" );
2506 exit( -1 );
2507 }
2508 }
2509
2510 /* block SIGUSR1 */
2511 sigemptyset( &my_sigset );
2512 sigaddset( &my_sigset, SIGUSR1 );
2513 if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) {
2514 printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2515 exit( -1 );
2516 }
2517 my_err = sigprocmask( SIG_BLOCK, &my_sigset, NULL );
2518 if ( my_err == -1 ) {
2519 printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2520 exit( -1 );
2521 }
2522
2523 /* make sure we are blocking SIGUSR1 */
2524 sigemptyset( &my_sigset );
2525 my_err = sigprocmask( 0, NULL, &my_sigset );
2526 if ( my_err == -1 ) {
2527 printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2528 exit( -1 );
2529 }
2530 if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) {
2531 printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2532 exit( -1 );
2533 }
2534
2535 /* our parent will send a 2nd SIGUSR1 signal which we should now see getting
2536 * blocked.
2537 */
2538 sigemptyset( &my_sigset );
2539 sigaddset( &my_sigset, SIGUSR1 );
2540 my_err = sigwait( &my_sigset, &my_signal );
2541 if ( my_err == -1 ) {
2542 printf( "sigwait failed with errno %d - %s \n", errno, strerror( errno ) );
2543 exit( -1 );
2544 }
2545 //printf( "%s - %d - signal 0x%02X %d \n", __FUNCTION__, __LINE__, my_signal, my_signal );
2546 if ( my_signal != SIGUSR1 ) {
2547 printf( "sigwait failed to catch a pending SIGUSR1 signal. \n" );
2548 exit( -1 );
2549 }
2550
2551 /* now unblock SIGUSR1 */
2552 sigfillset( &my_sigset );
2553 sigdelset( &my_sigset, SIGUSR1 );
2554 my_err = sigprocmask( SIG_UNBLOCK, &my_sigset, NULL );
2555 if ( my_err == -1 ) {
2556 printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) );
2557 exit( -1 );
2558 }
2559 if ( sigismember( &my_sigset, SIGUSR1 ) != 0 ) {
2560 printf( "sigprocmask call failed to unblock SIGUSR1 \n" );
2561 exit( -1 );
2562 }
2563
2564 /* test get / setitimer */
2565 timerclear( &my_timer.it_interval );
2566 timerclear( &my_timer.it_value );
2567 my_err = setitimer( ITIMER_VIRTUAL, &my_timer, NULL );
2568 if ( my_err == -1 ) {
2569 printf( "setitimer - ITIMER_VIRTUAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2570 exit( -1 );
2571 }
2572 my_err = setitimer( ITIMER_PROF, &my_timer, NULL );
2573 if ( my_err == -1 ) {
2574 printf( "setitimer - ITIMER_PROF - failed with errno %d - %s \n", errno, strerror( errno ) );
2575 exit( -1 );
2576 }
2577
2578 /* set up to catch SIGALRM */
2579 alarm_global = 0;
2580 my_sigaction.sa_handler = test_alarm_handler;
2581 my_sigaction.sa_flags = SA_RESTART;
2582 my_sigaction.sa_mask = 0;
2583
2584 my_err = sigaction( SIGALRM, &my_sigaction, NULL );
2585 if ( my_err == -1 ) {
2586 printf( "sigaction - SIGALRM - failed with errno %d - %s \n", errno, strerror( errno ) );
2587 exit( -1 );
2588 }
2589
2590 /* set timer for half a second */
2591 my_timer.it_value.tv_usec = (1000000 / 2);
2592 my_err = setitimer( ITIMER_REAL, &my_timer, NULL );
2593 if ( my_err == -1 ) {
2594 printf( "setitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2595 exit( -1 );
2596 }
2597
2598 /* now suspend until signal SIGALRM is sent */
2599 sigfillset( &my_sigset );
2600 sigdelset( &my_sigset, SIGALRM );
2601 my_err = sigsuspend( &my_sigset );
2602 if ( my_err == -1 ) {
2603 if ( errno != EINTR ) {
2604 printf( "sigsuspend should have returned with errno EINTR \n" );
2605 exit( -1 );
2606 }
2607 }
2608 if ( alarm_global != 4 ) {
2609 printf( "setitimer test failed - did not catch SIGALRM \n" );
2610 exit( -1 );
2611 }
2612
2613 /* make sure ITIMER_REAL is now clear */
2614 my_timer.it_value.tv_sec = 44;
2615 my_timer.it_value.tv_usec = 44;
2616 my_err = getitimer( ITIMER_REAL, &my_timer );
2617 if ( my_err == -1 ) {
2618 printf( "getitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) );
2619 exit( -1 );
2620 }
2621 if ( timerisset( &my_timer.it_value ) || timerisset( &my_timer.it_interval ) ) {
2622 printf( "ITIMER_REAL is set, but should not be \n" );
2623 exit( -1 );
2624 }
2625
2626 exit(0);
2627 }
2628
2629 /*
2630 * parent process - let child set up to suspend then signal it with SIGUSR1
2631 */
2632 sleep( 1 );
2633 my_err = kill( my_pid, SIGUSR1 );
2634 if ( my_err == -1 ) {
2635 printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2636 goto test_failed_exit;
2637 }
2638
2639 /* send 2nd signal to suspended child - which should be blocking SIGUSR1 signals */
2640 sleep( 1 );
2641 my_err = kill( my_pid, SIGUSR1 );
2642 if ( my_err == -1 ) {
2643 printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2644 goto test_failed_exit;
2645 }
2646
2647 /* wait for child to exit */
2648 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2649 if ( my_wait_pid == -1 ) {
2650 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2651 goto test_failed_exit;
2652 }
2653
2654 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2655 goto test_failed_exit;
2656 }
2657
2658 my_err = 0;
2659 goto test_passed_exit;
2660
2661 test_failed_exit:
2662 my_err = -1;
2663
2664 test_passed_exit:
2665 if ( my_fd != -1 )
2666 close( my_fd );
2667 if ( my_pathp != NULL ) {
2668 remove( my_pathp );
2669 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2670 }
2671 return( my_err );
2672 }
2673
2674 /* **************************************************************************************************************
2675 * Test getlogin, setlogin system calls.
2676 * **************************************************************************************************************
2677 */
2678 int getlogin_setlogin_test( void * the_argp )
2679 {
2680 int my_err, my_status;
2681 pid_t my_pid, my_wait_pid;
2682 kern_return_t my_kr;
2683
2684 if ( g_skip_setuid_tests != 0 ) {
2685 printf("\t skipping this test \n");
2686 my_err = 0;
2687 goto test_passed_exit;
2688 }
2689
2690 /*
2691 * spin off a child process that we will use for testing.
2692 */
2693 my_pid = fork( );
2694 if ( my_pid == -1 ) {
2695 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2696 goto test_failed_exit;
2697 }
2698 if ( my_pid == 0 ) {
2699 /*
2700 * child process - do getlogin and setlogin testing.
2701 */
2702 char * my_namep = NULL;
2703 int my_len;
2704 char * my_new_namep = NULL;
2705
2706 my_namep = getlogin( );
2707 if ( my_namep == NULL ) {
2708 printf( "getlogin returned NULL name pointer \n" );
2709 my_err = -1;
2710 goto exit_child;
2711 }
2712
2713 my_len = strlen( my_namep ) + 4;
2714
2715 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_namep, my_len, VM_FLAGS_ANYWHERE);
2716 if(my_kr != KERN_SUCCESS){
2717 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2718 my_err = -1;
2719 goto exit_child;
2720 }
2721
2722 bzero( (void *)my_new_namep, my_len );
2723
2724 strcat( my_new_namep, my_namep );
2725 strcat( my_new_namep, "2" );
2726
2727
2728 /* set new name */
2729 my_err = setlogin( my_new_namep );
2730 if ( my_err == -1 ) {
2731 printf( "When setting new login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) );
2732 my_err = -1;
2733 goto exit_child;
2734 }
2735
2736 /* make sure we set new name */
2737 my_namep = getlogin( );
2738 if ( my_namep == NULL ) {
2739 printf( "getlogin returned NULL name pointer \n" );
2740 my_err = -1;
2741 goto exit_child;
2742 }
2743
2744 if ( memcmp( my_namep, my_new_namep, strlen( my_new_namep ) ) != 0 ) {
2745 printf( "setlogin failed to set the new name \n" );
2746 my_err = -1;
2747 goto exit_child;
2748 }
2749
2750 /* reset to original name */
2751 my_len = strlen ( my_namep );
2752 my_namep[ my_len - 1 ] = '\0';
2753
2754 my_err = setlogin( my_namep );
2755 if ( my_err == -1 ) {
2756 printf( "When resetting login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) );
2757 my_err = -1;
2758 goto exit_child;
2759 }
2760
2761
2762 my_err = 0;
2763 exit_child:
2764 if ( my_new_namep != NULL ) {
2765 vm_deallocate(mach_task_self(), (vm_address_t)my_new_namep, my_len);
2766 }
2767 exit( my_err );
2768 }
2769
2770 /* parent process -
2771 * wait for child to exit
2772 */
2773 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2774 if ( my_wait_pid == -1 ) {
2775 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2776 goto test_failed_exit;
2777 }
2778
2779 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2780 goto test_failed_exit;
2781 }
2782 my_err = 0;
2783 goto test_passed_exit;
2784
2785 test_failed_exit:
2786 my_err = -1;
2787
2788 test_passed_exit:
2789 return( my_err );
2790 }
2791
2792 /* **************************************************************************************************************
2793 * Test acct system call.
2794 * **************************************************************************************************************
2795 */
2796 int acct_test( void * the_argp )
2797 {
2798 int my_err, my_status;
2799 int my_fd = -1;
2800 char * my_pathp = NULL;
2801 struct acct * my_acctp;
2802 pid_t my_pid, my_wait_pid;
2803 ssize_t my_count;
2804 char my_buffer[ (sizeof(struct acct) + 32) ];
2805 kern_return_t my_kr;
2806
2807 if ( g_skip_setuid_tests != 0 ) {
2808 printf("\t skipping this test \n");
2809 my_err = 0;
2810 goto test_passed_exit;
2811 }
2812
2813 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
2814 if(my_kr != KERN_SUCCESS){
2815 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
2816 goto test_failed_exit;
2817 }
2818
2819 *my_pathp = 0x00;
2820 strcat( my_pathp, &g_target_path[0] );
2821 strcat( my_pathp, "/" );
2822
2823 /* create a test file */
2824 my_err = create_random_name( my_pathp, 1 );
2825 if ( my_err != 0 ) {
2826 goto test_failed_exit;
2827 }
2828
2829 /* enable process accounting */
2830 my_err = acct( my_pathp );
2831 if ( my_err == -1 ) {
2832 printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2833 goto test_failed_exit;
2834 }
2835
2836 /*
2837 * spin off a child process that we will use for testing.
2838 */
2839 my_pid = fork( );
2840 if ( my_pid == -1 ) {
2841 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
2842 goto test_failed_exit;
2843 }
2844 if ( my_pid == 0 ) {
2845 char *argv[2]; /* supply valid argv array to execv() */
2846 argv[0] = "/usr/bin/true";
2847 argv[1] = 0;
2848
2849 /*
2850 * child process - do a little work then exit.
2851 */
2852 my_err = execv( argv[0], argv);
2853 exit( 0 );
2854 }
2855
2856 /* parent process -
2857 * wait for child to exit
2858 */
2859 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
2860 if ( my_wait_pid == -1 ) {
2861 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
2862 goto test_failed_exit;
2863 }
2864
2865 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
2866 printf("unexpected child exit status for accounting test load: %d\n", WEXITSTATUS( my_status));
2867 goto test_failed_exit;
2868 }
2869
2870 /* disable process accounting */
2871 my_err = acct( NULL );
2872 if ( my_err == -1 ) {
2873 printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) );
2874 goto test_failed_exit;
2875 }
2876
2877 /* now verify that there is accounting info in the log file */
2878 my_fd = open( my_pathp, O_RDONLY, 0 );
2879 if ( my_fd == -1 ) {
2880 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2881 goto test_failed_exit;
2882 }
2883
2884 lseek( my_fd, 0, SEEK_SET );
2885 bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
2886 my_count = read( my_fd, &my_buffer[0], sizeof(struct acct) );
2887 if ( my_count == -1 ) {
2888 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2889 goto test_failed_exit;
2890 }
2891
2892 my_acctp = (struct acct *) &my_buffer[0];
2893
2894 /* first letters in ac_comm should match the name of the executable */
2895 if ( getuid( ) != my_acctp->ac_uid || getgid( ) != my_acctp->ac_gid ||
2896 my_acctp->ac_comm[0] != 't' || my_acctp->ac_comm[1] != 'r' ) {
2897 printf( "------------------------\n" );
2898 printf( "my_acctp->ac_uid = %lu (should be: %lu)\n", (unsigned long) my_acctp->ac_uid, (unsigned long) getuid() );
2899 printf( "my_acctp->ac_gid = %lu (should be: %lu)\n", (unsigned long) my_acctp->ac_gid, (unsigned long) getgid() );
2900
2901 print_acct_debug_strings(my_acctp->ac_comm);
2902
2903 goto test_failed_exit;
2904 }
2905 my_err = 0;
2906 goto test_passed_exit;
2907
2908 test_failed_exit:
2909 my_err = -1;
2910
2911 test_passed_exit:
2912 if ( my_fd != -1 )
2913 close( my_fd );
2914 if ( my_pathp != NULL ) {
2915 remove( my_pathp );
2916 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
2917 }
2918 return( my_err );
2919 }
2920
2921 void print_acct_debug_strings( char * my_ac_comm )
2922 {
2923 char my_cmd_str[11]; /* sizeof(acct_cmd) + 1 for '\0' if acct_cmd is bogus */
2924 char my_hex_str[128];
2925 int i;
2926
2927 my_hex_str[0] = '\0';
2928 for(i = 0; i < 10; i++)
2929 {
2930 sprintf( my_hex_str, "%s \'0x%x\' ", my_hex_str, my_ac_comm[i]);
2931 }
2932
2933 memccpy(my_cmd_str, my_ac_comm, '\0', 10);
2934 my_cmd_str[10] = '\0'; /* In case ac_comm was bogus */
2935
2936
2937 printf( "my_acctp->ac_comm = \"%s\" (should begin with: \"tr\")\n", my_cmd_str);
2938 printf( "my_acctp->ac_comm = \"%s\"\n", my_hex_str);
2939 printf( "------------------------\n" );
2940 }
2941
2942
2943 /* **************************************************************************************************************
2944 * Test ioctl system calls.
2945 * **************************************************************************************************************
2946 */
2947 int ioctl_test( void * the_argp )
2948 {
2949 int my_err, my_result;
2950 int my_fd = -1;
2951 struct statfs * my_infop;
2952 char * my_ptr;
2953 int my_blksize;
2954 long long my_block_count;
2955 char my_name[ 128 ];
2956
2957 my_result = getmntinfo( &my_infop, MNT_NOWAIT );
2958 if ( my_result < 1 ) {
2959 printf( "getmntinfo failed with error %d - \"%s\" \n", errno, strerror( errno) );
2960 goto test_failed_exit;
2961 }
2962
2963 /* make this a raw device */
2964 strcpy( &my_name[0], &my_infop->f_mntfromname[0] );
2965 if ( (my_ptr = strrchr( &my_name[0], '/' )) != 0 ) {
2966 if ( my_ptr[1] != 'r' ) {
2967 my_ptr[ strlen( my_ptr ) ] = 0x00;
2968 memmove( &my_ptr[2], &my_ptr[1], (strlen( &my_ptr[1] ) + 1) );
2969 my_ptr[1] = 'r';
2970 }
2971 }
2972
2973 my_fd = open(&my_name[0], O_RDONLY );
2974 if ( my_fd == -1 ) {
2975 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
2976 goto test_failed_exit;
2977 }
2978
2979 /* obtain the size of the media (in blocks) */
2980 my_err = ioctl( my_fd, DKIOCGETBLOCKCOUNT, &my_block_count );
2981 if ( my_err == -1 ) {
2982 printf( "ioctl DKIOCGETBLOCKCOUNT failed with error %d - \"%s\" \n", errno, strerror( errno) );
2983 goto test_failed_exit;
2984 }
2985
2986 /* obtain the block size of the media */
2987 my_err = ioctl( my_fd, DKIOCGETBLOCKSIZE, &my_blksize );
2988 if ( my_err == -1 ) {
2989 printf( "ioctl DKIOCGETBLOCKSIZE failed with error %d - \"%s\" \n", errno, strerror( errno) );
2990 goto test_failed_exit;
2991 }
2992 //printf( "my_block_count %qd my_blksize %d \n", my_block_count, my_blksize );
2993
2994 /* make sure the returned data looks somewhat valid */
2995 if ( my_blksize < 0 || my_blksize > (1024 * 1000) ) {
2996 printf( "ioctl appears to have returned incorrect block size data \n" );
2997 goto test_failed_exit;
2998 }
2999
3000 my_err = 0;
3001 goto test_passed_exit;
3002
3003 test_failed_exit:
3004 my_err = -1;
3005
3006 test_passed_exit:
3007 if ( my_fd != -1 )
3008 close( my_fd );
3009 return( my_err );
3010 }
3011
3012 /* **************************************************************************************************************
3013 * Test mkdir, rmdir, umask system calls.
3014 * **************************************************************************************************************
3015 */
3016 int mkdir_rmdir_umask_test( void * the_argp )
3017 {
3018 int my_err;
3019 int my_fd = -1;
3020 int did_umask = 0;
3021 char * my_pathp = NULL;
3022 mode_t my_orig_mask;
3023 struct stat my_sb;
3024 kern_return_t my_kr;
3025
3026 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3027 if(my_kr != KERN_SUCCESS){
3028 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3029 goto test_failed_exit;
3030 }
3031
3032 *my_pathp = 0x00;
3033 strcat( my_pathp, &g_target_path[0] );
3034 strcat( my_pathp, "/" );
3035
3036 /* get a unique name to use with mkdir */
3037 my_err = create_random_name( my_pathp, 0 );
3038 if ( my_err != 0 ) {
3039 printf( "create_random_name failed with error %d\n", my_err );
3040 goto test_failed_exit;
3041 }
3042
3043 /* set umask to clear WX for other and group and clear X for user */
3044 my_orig_mask = umask( (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) );
3045 did_umask = 1;
3046
3047 /* create a directory with RWX for user, group, other (which should be limited by umask) */
3048 my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3049 if ( my_err == -1 ) {
3050 printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3051 goto test_failed_exit;
3052 }
3053
3054 /* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/
3055 my_err = stat( my_pathp, &my_sb );
3056 if ( my_err != 0 ) {
3057 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3058 goto test_failed_exit;
3059 }
3060 if ( (my_sb.st_mode & (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH)) != 0 ) {
3061 printf( "umask did not limit modes as it should have \n" );
3062 goto test_failed_exit;
3063 }
3064
3065 /* get rid of our test directory */
3066 my_err = rmdir( my_pathp );
3067 if ( my_err == -1 ) {
3068 printf( "rmdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3069 goto test_failed_exit;
3070 }
3071 my_err = 0;
3072 goto test_passed_exit;
3073
3074 test_failed_exit:
3075 my_err = -1;
3076
3077 test_passed_exit:
3078 if ( my_fd != -1 )
3079 close( my_fd );
3080 if ( my_pathp != NULL ) {
3081 rmdir( my_pathp );
3082 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3083 }
3084 if ( did_umask != 0 ) {
3085 umask( my_orig_mask );
3086 }
3087
3088 return( my_err );
3089 }
3090
3091 /* **************************************************************************************************************
3092 * Test chroot system call.
3093 * **************************************************************************************************************
3094 */
3095 int chroot_test( void * the_argp )
3096 {
3097 int my_err, my_status;
3098 pid_t my_pid, my_wait_pid;
3099 char * my_pathp = NULL;
3100 kern_return_t my_kr;
3101
3102 if ( g_skip_setuid_tests != 0 ) {
3103 printf("\t skipping this test \n");
3104 my_err = 0;
3105 goto test_passed_exit;
3106 }
3107
3108 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3109 if(my_kr != KERN_SUCCESS){
3110 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3111 goto test_failed_exit;
3112 }
3113
3114 *my_pathp = 0x00;
3115 strcat( my_pathp, &g_target_path[0] );
3116 strcat( my_pathp, "/" );
3117
3118 /* get a unique name for our test directory */
3119 my_err = create_random_name( my_pathp, 0 );
3120 if ( my_err != 0 ) {
3121 goto test_failed_exit;
3122 }
3123
3124 /* create a test directory */
3125 my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) );
3126 if ( my_err == -1 ) {
3127 printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) );
3128 goto test_failed_exit;
3129 }
3130
3131 /*
3132 * spin off a child process that we will use for testing.
3133 */
3134 my_pid = fork( );
3135 if ( my_pid == -1 ) {
3136 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3137 goto test_failed_exit;
3138 }
3139 if ( my_pid == 0 ) {
3140 /*
3141 * child process - do getlogin and setlogin testing.
3142 */
3143 struct stat my_sb;
3144
3145 /* change our root to our new test directory */
3146 my_err = chroot( my_pathp );
3147 if ( my_err != 0 ) {
3148 printf( "chroot failed with error %d - \"%s\" \n", errno, strerror( errno) );
3149 exit( -1 );
3150 }
3151
3152 /* verify root directory is now an empty directory */
3153 my_err = stat( "/", &my_sb );
3154 if ( my_err != 0 ) {
3155 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3156 exit( -1 );
3157 }
3158 if ( my_sb.st_nlink > 2 ) {
3159 printf( "root dir should be emnpty! \n" );
3160 exit( -1 );
3161 }
3162 exit( 0 );
3163 }
3164
3165 /* parent process -
3166 * wait for child to exit
3167 */
3168 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3169 if ( my_wait_pid == -1 ) {
3170 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3171 goto test_failed_exit;
3172 }
3173
3174 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3175 printf( "bad exit status\n" );
3176 goto test_failed_exit;
3177 }
3178
3179 my_err = 0;
3180 goto test_passed_exit;
3181
3182 test_failed_exit:
3183 my_err = -1;
3184
3185 test_passed_exit:
3186 if ( my_pathp != NULL ) {
3187 my_err = rmdir( my_pathp );
3188 if ( my_err != 0 ) {
3189 printf( "rmdir failed with error %d - \"%s\" path %p\n", errno, strerror( errno), my_pathp );
3190 }
3191 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3192 }
3193 return( my_err );
3194 }
3195
3196 /* **************************************************************************************************************
3197 * Test getpgrp, getpgid, getsid, setpgid, setpgrp, setsid system calls.
3198 * **************************************************************************************************************
3199 */
3200 int process_group_test( void * the_argp )
3201 {
3202 int my_err = 0, i = 0;
3203 pid_t my_session_id, my_pid, my_process_group;
3204
3205 /* get current session ID, pgid, and pid */
3206 my_session_id = getsid( 0 );
3207 if ( my_session_id == -1 ) {
3208 printf( "getsid call failed with error %d - \"%s\" \n",
3209 errno, strerror( errno ) );
3210 goto test_failed_exit;
3211 }
3212
3213 my_pid = getpid( );
3214 my_process_group = getpgrp( );
3215
3216 /* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */
3217 if ( my_process_group != getpgid( 0 ) ) {
3218 printf( "getpgrp and getpgid did not return the same process group ID \n" );
3219 printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group );
3220 goto test_failed_exit;
3221 }
3222
3223 if ( my_pid == my_process_group ) {
3224 /* we are process group leader */
3225 my_err = setsid( );
3226 if ( my_err == 0 || errno != EPERM ) {
3227 printf( "setsid call should have failed with EPERM\n" );
3228 goto test_failed_exit;
3229 }
3230 } else {
3231 /* we are not process group leader: try creating new session */
3232 my_err = setsid( );
3233 if ( my_err == -1 ) {
3234 printf( "setsid call failed with error %d - \"%s\" \n",
3235 errno, strerror( errno ) );
3236 goto test_failed_exit;
3237 }
3238
3239 if ( my_process_group == getpgid( 0 ) ) {
3240 printf( "process group was not reset \n" );
3241 goto test_failed_exit;
3242 }
3243 }
3244
3245 /* find an unused process group ID */
3246 for ( i = 10000; i < 1000000; i++ ) {
3247 my_process_group = getpgid( i );
3248 if ( my_process_group == -1 ) {
3249 break;
3250 }
3251 }
3252
3253 /* this should fail */
3254 my_err = setpgid( 0, my_process_group );
3255 if ( my_err != -1 ) {
3256 printf( "setpgid should have failed, but did not \n" );
3257 goto test_failed_exit;
3258 }
3259
3260 my_err = 0;
3261 goto test_passed_exit;
3262
3263 test_failed_exit:
3264 my_err = -1;
3265
3266 test_passed_exit:
3267 return( my_err );
3268 }
3269
3270 /* **************************************************************************************************************
3271 * Test fcntl system calls.
3272 * **************************************************************************************************************
3273 */
3274 int fcntl_test( void * the_argp )
3275 {
3276 int my_err, my_result, my_tmep;
3277 int my_fd = -1;
3278 int my_newfd = -1;
3279 char * my_pathp = NULL;
3280 kern_return_t my_kr;
3281
3282 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3283 if(my_kr != KERN_SUCCESS){
3284 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3285 goto test_failed_exit;
3286 }
3287
3288 *my_pathp = 0x00;
3289 strcat( my_pathp, &g_target_path[0] );
3290 strcat( my_pathp, "/" );
3291
3292 /* create a test file */
3293 my_err = create_random_name( my_pathp, 1 );
3294 if ( my_err != 0 ) {
3295 goto test_failed_exit;
3296 }
3297
3298 /* open our test file and use fcntl to get / set file descriptor flags */
3299 my_fd = open( my_pathp, O_RDONLY, 0 );
3300 if ( my_fd == -1 ) {
3301 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3302 goto test_failed_exit;
3303 }
3304
3305 my_result = fcntl( my_fd, F_GETFD, 0 );
3306 if ( my_result == -1 ) {
3307 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3308 goto test_failed_exit;
3309 }
3310
3311 my_tmep = (my_result & FD_CLOEXEC);
3312 if ( my_tmep ) {
3313 /* FD_CLOEXEC is on, let's turn it off */
3314 my_result = fcntl( my_fd, F_SETFD, 0 );
3315 }
3316 else {
3317 /* FD_CLOEXEC is off, let's turn it on */
3318 my_result = fcntl( my_fd, F_SETFD, 1 );
3319 }
3320 if ( my_result == -1 ) {
3321 printf( "fcntl - F_SETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3322 goto test_failed_exit;
3323 }
3324
3325 /* now check to see if it is set correctly */
3326 my_result = fcntl( my_fd, F_GETFD, 0 );
3327 if ( my_result == -1 ) {
3328 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3329 goto test_failed_exit;
3330 }
3331 if ( my_tmep == (my_result & 0x01) ) {
3332 printf( "fcntl - F_SETFD failed to set FD_CLOEXEC correctly!!! \n" );
3333 goto test_failed_exit;
3334 }
3335
3336 /* dup it to a new fd with FD_CLOEXEC forced on */
3337
3338 my_result = fcntl( my_fd, F_DUPFD_CLOEXEC, 0);
3339 if ( my_result == -1 ) {
3340 printf( "fcntl - F_DUPFD_CLOEXEC - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3341 goto test_failed_exit;
3342 }
3343 my_newfd = my_result;
3344
3345 /* check to see that it too is marked with FD_CLOEXEC */
3346
3347 my_result = fcntl( my_newfd, F_GETFD, 0);
3348 if ( my_result == -1 ) {
3349 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3350 goto test_failed_exit;
3351 }
3352 if ( (my_result & FD_CLOEXEC) == 0 ) {
3353 printf( "fcntl - F_DUPFD_CLOEXEC failed to set FD_CLOEXEC!!! \n" );
3354 goto test_failed_exit;
3355 }
3356
3357 close( my_newfd );
3358 my_newfd = -1;
3359
3360 /* While we're here, dup it via an open of /dev/fd/<fd> .. */
3361
3362 {
3363 char devfdpath[PATH_MAX];
3364
3365 (void) snprintf( devfdpath, sizeof (devfdpath),
3366 "/dev/fd/%u", my_fd );
3367 my_result = open( devfdpath, O_RDONLY | O_CLOEXEC );
3368 }
3369 if ( my_result == -1 ) {
3370 printf( "open call failed on /dev/fd/%u with error %d - \"%s\" \n", my_fd, errno, strerror( errno) );
3371 goto test_failed_exit;
3372 }
3373 my_newfd = my_result;
3374
3375 /* check to see that it too is marked with FD_CLOEXEC */
3376
3377 my_result = fcntl( my_newfd, F_GETFD, 0);
3378 if ( my_result == -1 ) {
3379 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3380 goto test_failed_exit;
3381 }
3382 if ( (my_result & FD_CLOEXEC) == 0 ) {
3383 printf( "fcntl - O_CLOEXEC open of /dev/fd/%u failed to set FD_CLOEXEC!!! \n", my_fd );
3384 goto test_failed_exit;
3385 }
3386 close ( my_newfd );
3387 my_newfd = -1;
3388
3389 my_err = 0;
3390 goto test_passed_exit;
3391
3392 test_failed_exit:
3393 my_err = -1;
3394
3395 test_passed_exit:
3396 if ( my_newfd != -1)
3397 close ( my_newfd );
3398 if ( my_fd != -1 )
3399 close( my_fd );
3400 if ( my_pathp != NULL ) {
3401 remove( my_pathp );
3402 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3403 }
3404 return( my_err );
3405 }
3406
3407 /* **************************************************************************************************************
3408 * Test getpriority, setpriority system calls.
3409 * **************************************************************************************************************
3410 */
3411 int getpriority_setpriority_test( void * the_argp )
3412 {
3413 int my_err;
3414 int my_priority;
3415 int my_new_priority;
3416
3417 /* getpriority returns scheduling priority so -1 is a valid value */
3418 errno = 0;
3419 my_priority = getpriority( PRIO_PROCESS, 0 );
3420 if ( my_priority == -1 && errno != 0 ) {
3421 printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3422 goto test_failed_exit;
3423 }
3424
3425 /* change scheduling priority */
3426 my_new_priority = (my_priority == PRIO_MIN) ? (my_priority + 10) : (PRIO_MIN);
3427 my_err = setpriority( PRIO_PROCESS, 0, my_new_priority );
3428 if ( my_err == -1 ) {
3429 printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3430 goto test_failed_exit;
3431 }
3432
3433 /* verify change */
3434 errno = 0;
3435 my_priority = getpriority( PRIO_PROCESS, 0 );
3436 if ( my_priority == -1 && errno != 0 ) {
3437 printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3438 goto test_failed_exit;
3439 }
3440
3441 if ( my_priority != my_new_priority ) {
3442 printf( "setpriority - failed to set correct scheduling priority \n" );
3443 goto test_failed_exit;
3444 }
3445
3446 /* reset scheduling priority */
3447 my_err = setpriority( PRIO_PROCESS, 0, 0 );
3448 if ( my_err == -1 ) {
3449 printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3450 goto test_failed_exit;
3451 }
3452
3453 my_err = 0;
3454 goto test_passed_exit;
3455
3456 test_failed_exit:
3457 my_err = -1;
3458
3459 test_passed_exit:
3460 return( my_err );
3461 }
3462
3463 /* **************************************************************************************************************
3464 * Test futimes, gettimeofday, settimeofday, utimes system calls.
3465 * **************************************************************************************************************
3466 */
3467 int time_tests( void * the_argp )
3468 {
3469 int my_err;
3470 int my_fd = -1;
3471 char * my_pathp = NULL;
3472 struct timeval my_orig_time;
3473 struct timeval my_temp_time;
3474 struct timeval my_utimes[4];
3475 struct timezone my_tz;
3476 struct stat my_sb;
3477 kern_return_t my_kr;
3478
3479 if ( g_skip_setuid_tests != 0 ) {
3480 printf( "\t skipping this test \n" );
3481 my_err = 0;
3482 goto test_passed_exit;
3483 }
3484
3485 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3486 if(my_kr != KERN_SUCCESS){
3487 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3488 goto test_failed_exit;
3489 }
3490
3491 *my_pathp = 0x00;
3492 strcat( my_pathp, &g_target_path[0] );
3493 strcat( my_pathp, "/" );
3494
3495 /* create a test file */
3496 my_err = create_random_name( my_pathp, 1 );
3497 if ( my_err != 0 ) {
3498 goto test_failed_exit;
3499 }
3500
3501 my_err = gettimeofday( &my_orig_time, &my_tz );
3502 if ( my_err == -1 ) {
3503 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3504 goto test_failed_exit;
3505 }
3506 //printf( "tv_sec %d tv_usec %ld \n", my_orig_time.tv_sec, my_orig_time.tv_usec );
3507
3508 my_temp_time = my_orig_time;
3509 my_temp_time.tv_sec -= 60;
3510 my_err = settimeofday( &my_temp_time, NULL );
3511 if ( my_err == -1 ) {
3512 printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3513 goto test_failed_exit;
3514 }
3515
3516 my_err = gettimeofday( &my_temp_time, NULL );
3517 if ( my_err == -1 ) {
3518 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3519 goto test_failed_exit;
3520 }
3521 //printf( "tv_sec %d tv_usec %ld \n", my_temp_time.tv_sec, my_temp_time.tv_usec );
3522 if ( my_orig_time.tv_sec <= my_temp_time.tv_sec ) {
3523 printf( "settimeofday did not set correct time \n" );
3524 goto test_failed_exit;
3525 }
3526
3527 /* set time back to original value plus 1 second */
3528 my_temp_time = my_orig_time;
3529 my_temp_time.tv_sec += 1;
3530 my_err = settimeofday( &my_temp_time, NULL );
3531 if ( my_err == -1 ) {
3532 printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3533 goto test_failed_exit;
3534 }
3535
3536 /* test utimes and futimes - get current access and mod times then change them */
3537 my_err = stat( my_pathp, &my_sb );
3538 if ( my_err != 0 ) {
3539 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3540 goto test_failed_exit;
3541 }
3542 TIMESPEC_TO_TIMEVAL( &my_utimes[0], &my_sb.st_atimespec );
3543 TIMESPEC_TO_TIMEVAL( &my_utimes[1], &my_sb.st_mtimespec );
3544 my_utimes[0].tv_sec -= 120; /* make access time 2 minutes older */
3545 my_utimes[1].tv_sec -= 120; /* make mod time 2 minutes older */
3546
3547 my_err = utimes( my_pathp, &my_utimes[0] );
3548 if ( my_err == -1 ) {
3549 printf( "utimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3550 goto test_failed_exit;
3551 }
3552
3553 /* make sure the correct times are set */
3554 my_err = stat( my_pathp, &my_sb );
3555 if ( my_err != 0 ) {
3556 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3557 goto test_failed_exit;
3558 }
3559 TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3560 TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3561 if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3562 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3563 printf( "utimes failed to set access and mod times \n" );
3564 goto test_failed_exit;
3565 }
3566
3567 my_fd = open( my_pathp, O_RDWR, 0 );
3568 if ( my_fd == -1 ) {
3569 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3570 goto test_failed_exit;
3571 }
3572
3573 my_utimes[0].tv_sec -= 120; /* make access time 2 minutes older */
3574 my_utimes[1].tv_sec -= 120; /* make mod time 2 minutes older */
3575 my_err = futimes( my_fd, &my_utimes[0] );
3576 if ( my_err == -1 ) {
3577 printf( "futimes - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3578 goto test_failed_exit;
3579 }
3580
3581 /* make sure the correct times are set */
3582 my_err = stat( my_pathp, &my_sb );
3583 if ( my_err != 0 ) {
3584 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3585 goto test_failed_exit;
3586 }
3587 TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec );
3588 TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec );
3589 if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec ||
3590 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) {
3591 printf( "futimes failed to set access and mod times \n" );
3592 goto test_failed_exit;
3593 }
3594
3595 my_err = 0;
3596 goto test_passed_exit;
3597
3598 test_failed_exit:
3599 my_err = -1;
3600
3601 test_passed_exit:
3602 if ( my_fd != -1 )
3603 close( my_fd );
3604 if ( my_pathp != NULL ) {
3605 remove( my_pathp );
3606 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3607 }
3608 return( my_err );
3609 }
3610
3611 /* **************************************************************************************************************
3612 * Test rename, stat system calls.
3613 * **************************************************************************************************************
3614 */
3615 int rename_test( void * the_argp )
3616 {
3617 int my_err;
3618 char * my_pathp = NULL;
3619 char * my_new_pathp = NULL;
3620 ino_t my_file_id;
3621 struct stat my_sb;
3622 kern_return_t my_kr;
3623
3624 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3625 if(my_kr != KERN_SUCCESS){
3626 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3627 goto test_failed_exit;
3628 }
3629
3630 *my_pathp = 0x00;
3631 strcat( my_pathp, &g_target_path[0] );
3632 strcat( my_pathp, "/" );
3633
3634 /* create a test file */
3635 my_err = create_random_name( my_pathp, 1 );
3636 if ( my_err != 0 ) {
3637 goto test_failed_exit;
3638 }
3639
3640 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3641 if(my_kr != KERN_SUCCESS){
3642 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3643 goto test_failed_exit;
3644 }
3645
3646 *my_new_pathp = 0x00;
3647 strcat( my_new_pathp, &g_target_path[0] );
3648 strcat( my_new_pathp, "/" );
3649
3650 /* get a unique name for our rename test */
3651 my_err = create_random_name( my_new_pathp, 0 );
3652 if ( my_err != 0 ) {
3653 goto test_failed_exit;
3654 }
3655
3656 /* save file ID for later use */
3657 my_err = stat( my_pathp, &my_sb );
3658 if ( my_err != 0 ) {
3659 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3660 goto test_failed_exit;
3661 }
3662 my_file_id = my_sb.st_ino;
3663
3664 /* test rename */
3665 my_err = rename( my_pathp, my_new_pathp );
3666 if ( my_err == -1 ) {
3667 printf( "rename - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3668 goto test_failed_exit;
3669 }
3670
3671 /* make sure old name is no longer there */
3672 my_err = stat( my_pathp, &my_sb );
3673 if ( my_err == 0 ) {
3674 printf( "rename call failed - found old name \n" );
3675 goto test_failed_exit;
3676 }
3677
3678 /* make sure new name is there and is correct file id */
3679 my_err = stat( my_new_pathp, &my_sb );
3680 if ( my_err != 0 ) {
3681 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3682 goto test_failed_exit;
3683 }
3684 if ( my_file_id != my_sb.st_ino ) {
3685 printf( "rename failed - wrong file id \n" );
3686 goto test_failed_exit;
3687 }
3688
3689 my_err = 0;
3690 goto test_passed_exit;
3691
3692 test_failed_exit:
3693 my_err = -1;
3694
3695 test_passed_exit:
3696 if ( my_pathp != NULL ) {
3697 remove( my_pathp );
3698 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3699 }
3700 if ( my_new_pathp != NULL ) {
3701 remove( my_new_pathp );
3702 vm_deallocate(mach_task_self(), (vm_address_t)my_new_pathp, PATH_MAX);
3703 }
3704 return( my_err );
3705 }
3706
3707 /* **************************************************************************************************************
3708 * Test locking system calls.
3709 * **************************************************************************************************************
3710 */
3711 int locking_test( void * the_argp )
3712 {
3713 int my_err, my_status;
3714 pid_t my_pid, my_wait_pid;
3715 int my_fd = -1;
3716 char * my_pathp = NULL;
3717 kern_return_t my_kr;
3718
3719 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3720 if(my_kr != KERN_SUCCESS){
3721 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3722 goto test_failed_exit;
3723 }
3724
3725 *my_pathp = 0x00;
3726 strcat( my_pathp, &g_target_path[0] );
3727 strcat( my_pathp, "/" );
3728
3729 /* create a test file */
3730 my_err = create_random_name( my_pathp, 1 );
3731 if ( my_err != 0 ) {
3732 goto test_failed_exit;
3733 }
3734
3735 /* test flock */
3736 my_fd = open( my_pathp, O_RDWR, 0 );
3737 if ( my_fd == -1 ) {
3738 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3739 goto test_failed_exit;
3740 }
3741
3742 my_err = flock( my_fd, LOCK_EX );
3743 if ( my_err == -1 ) {
3744 printf( "flock - LOCK_EX - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3745 goto test_failed_exit;
3746 }
3747
3748 /*
3749 * spin off a child process that we will use for testing.
3750 */
3751 my_pid = fork( );
3752 if ( my_pid == -1 ) {
3753 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3754 goto test_failed_exit;
3755 }
3756 if ( my_pid == 0 ) {
3757 /*
3758 * child process.
3759 */
3760 int my_child_fd = -1;
3761 int my_child_err;
3762
3763 my_child_fd = open( my_pathp, O_RDWR, 0 );
3764 if ( my_child_fd == -1 ) {
3765 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3766 my_child_err = -1;
3767 goto child_exit;
3768 }
3769
3770 my_err = flock( my_child_fd, (LOCK_EX | LOCK_NB) );
3771 if ( my_err == -1 ) {
3772 if ( errno != EWOULDBLOCK ) {
3773 printf( "flock call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3774 my_child_err = -1;
3775 goto child_exit;
3776 }
3777 }
3778 else {
3779 printf( "flock call should have failed with EWOULDBLOCK err \n" );
3780 my_child_err = -1;
3781 goto child_exit;
3782 }
3783 my_child_err = 0;
3784 child_exit:
3785 if ( my_child_fd != -1 )
3786 close( my_child_fd );
3787 exit( my_child_err );
3788 }
3789
3790 /* parent process -
3791 * wait for child to exit
3792 */
3793 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3794 if ( my_wait_pid == -1 ) {
3795 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3796 goto test_failed_exit;
3797 }
3798
3799 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3800 goto test_failed_exit;
3801 }
3802
3803 my_err = flock( my_fd, LOCK_UN );
3804 if ( my_err == -1 ) {
3805 printf( "flock - LOCK_UN - failed with error %d - \"%s\" \n", errno, strerror( errno) );
3806 goto test_failed_exit;
3807 }
3808
3809 my_err = 0;
3810 goto test_passed_exit;
3811
3812 test_failed_exit:
3813 my_err = -1;
3814
3815 test_passed_exit:
3816 if ( my_fd != -1 )
3817 close( my_fd );
3818 if ( my_pathp != NULL ) {
3819 remove( my_pathp );
3820 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3821 }
3822 return( my_err );
3823 }
3824
3825 /* **************************************************************************************************************
3826 * Test mkfifo system calls.
3827 * **************************************************************************************************************
3828 */
3829 int mkfifo_test( void * the_argp )
3830 {
3831 int my_err, my_status;
3832 pid_t my_pid, my_wait_pid;
3833 int my_fd = -1;
3834 char * my_pathp = NULL;
3835 ssize_t my_result;
3836 off_t my_current_offset;
3837 kern_return_t my_kr;
3838
3839 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
3840 if(my_kr != KERN_SUCCESS){
3841 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
3842 goto test_failed_exit;
3843 }
3844
3845 *my_pathp = 0x00;
3846 strcat( my_pathp, &g_target_path[0] );
3847 strcat( my_pathp, "/" );
3848
3849 /* get unique name for our fifo */
3850 my_err = create_random_name( my_pathp, 0 );
3851 if ( my_err != 0 ) {
3852 goto test_failed_exit;
3853 }
3854
3855 my_err = mkfifo( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
3856 if ( my_err != 0 ) {
3857 printf( "mkfifo failed with errno %d - %s. \n", errno, strerror( errno ) );
3858 goto test_failed_exit;
3859 }
3860
3861 /*
3862 * spin off a child process that we will use for testing.
3863 */
3864 my_pid = fork( );
3865 if ( my_pid == -1 ) {
3866 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
3867 goto test_failed_exit;
3868 }
3869 if ( my_pid == 0 ) {
3870 /*
3871 * child process.
3872 */
3873 int my_child_fd = -1;
3874 int my_child_err;
3875 char my_buffer[64];
3876
3877 /* open read end of fifo */
3878 my_child_fd = open( my_pathp, O_RDWR, 0 );
3879 if ( my_child_fd == -1 ) {
3880 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3881 my_child_err = -1;
3882 goto child_exit;
3883 }
3884
3885 /* read message from parent */
3886 bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
3887 my_result = read( my_child_fd, &my_buffer[0], sizeof(my_buffer) );
3888 if ( my_result == -1 ) {
3889 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3890 my_child_err = -1;
3891 goto child_exit;
3892 }
3893 if ( strcmp( "parent to child", &my_buffer[0] ) != 0 ) {
3894 printf( "read wrong message from parent \n" );
3895 my_child_err = -1;
3896 goto child_exit;
3897 }
3898
3899 my_child_err = 0;
3900 child_exit:
3901 if ( my_child_fd != -1 )
3902 close( my_child_fd );
3903 exit( my_child_err );
3904 }
3905
3906 /* parent process - open write end of fifo
3907 */
3908 my_fd = open( my_pathp, O_WRONLY, 0 );
3909 if ( my_fd == -1 ) {
3910 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3911 goto test_failed_exit;
3912 }
3913
3914 /* make sure we can't seek on a fifo */
3915 my_current_offset = lseek( my_fd, 0, SEEK_CUR );
3916 if ( my_current_offset != -1 ) {
3917 printf( "lseek on fifo should fail but did not \n" );
3918 goto test_failed_exit;
3919 }
3920
3921 my_result = write( my_fd, "parent to child", 15 );
3922 if ( my_result == -1 ) {
3923 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
3924 goto test_failed_exit;
3925 }
3926
3927 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
3928 if ( my_wait_pid == -1 ) {
3929 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
3930 goto test_failed_exit;
3931 }
3932
3933 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
3934 goto test_failed_exit;
3935 }
3936
3937 my_err = 0;
3938 goto test_passed_exit;
3939
3940 test_failed_exit:
3941 my_err = -1;
3942
3943 test_passed_exit:
3944 if ( my_fd != -1 )
3945 close( my_fd );
3946 if ( my_pathp != NULL ) {
3947 remove( my_pathp );
3948 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
3949 }
3950 return( my_err );
3951 }
3952
3953 /* **************************************************************************************************************
3954 * Test quotactl system calls.
3955 * **************************************************************************************************************
3956 */
3957 int quotactl_test( void * the_argp )
3958 {
3959 #if !TARGET_OS_EMBEDDED
3960 int my_err;
3961 int is_quotas_on = 0;
3962 struct dqblk my_quota_blk;
3963
3964 if ( g_skip_setuid_tests != 0 ) {
3965 printf( "\t skipping this test \n" );
3966 my_err = 0;
3967 goto test_passed_exit;
3968 }
3969
3970 /* start off by checking the status of quotas on the boot volume */
3971 my_err = quotactl( "/mach_kernel", QCMD(Q_QUOTASTAT, USRQUOTA), 0, (caddr_t)&is_quotas_on );
3972 if ( my_err == -1 ) {
3973 printf( "quotactl - Q_QUOTASTAT - failed with errno %d - %s \n", errno, strerror( errno ) );
3974 goto test_failed_exit;
3975 }
3976
3977 if ( is_quotas_on == 0 ) {
3978 /* quotas are off */
3979 my_err = 0;
3980 goto test_passed_exit;
3981 }
3982
3983 my_err = quotactl( "/mach_kernel", QCMD(Q_GETQUOTA, USRQUOTA), getuid(), (caddr_t)&my_quota_blk );
3984 if ( my_err == -1 ) {
3985 printf( "quotactl - Q_GETQUOTA - failed with errno %d - %s \n", errno, strerror( errno ) );
3986 goto test_failed_exit;
3987 }
3988
3989 my_err = 0;
3990 goto test_passed_exit;
3991
3992 test_failed_exit:
3993 my_err = -1;
3994
3995 test_passed_exit:
3996 return( my_err );
3997 #else
3998 printf( "\t--> Not supported on EMBEDDED TARGET\n" );
3999 return 0;
4000 #endif
4001 }
4002
4003 /* **************************************************************************************************************
4004 * Test getrlimit, setrlimit system calls.
4005 * **************************************************************************************************************
4006 */
4007 int limit_tests( void * the_argp )
4008 {
4009 int my_err;
4010 struct rlimit my_current_rlimit;
4011 struct rlimit my_rlimit;
4012
4013 my_err = getrlimit( RLIMIT_NOFILE, &my_current_rlimit );
4014 if ( my_err == -1 ) {
4015 printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4016 goto test_failed_exit;
4017 }
4018 if ( my_current_rlimit.rlim_cur != RLIM_INFINITY ) {
4019 if ( my_current_rlimit.rlim_cur != my_current_rlimit.rlim_max )
4020 my_current_rlimit.rlim_cur += 1;
4021 else
4022 my_current_rlimit.rlim_cur -= 1;
4023 my_rlimit.rlim_cur = my_current_rlimit.rlim_cur;
4024 my_rlimit.rlim_max = my_current_rlimit.rlim_max;
4025 my_err = setrlimit( RLIMIT_NOFILE, &my_rlimit );
4026 if ( my_err == -1 ) {
4027 printf( "setrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4028 goto test_failed_exit;
4029 }
4030
4031 /* verify that we set a new limit */
4032 bzero( (void *) &my_rlimit, sizeof( my_rlimit ) );
4033 my_err = getrlimit( RLIMIT_NOFILE, &my_rlimit );
4034 if ( my_err == -1 ) {
4035 printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) );
4036 goto test_failed_exit;
4037 }
4038 if ( my_rlimit.rlim_cur != my_current_rlimit.rlim_cur ) {
4039 printf( "failed to get/set new RLIMIT_NOFILE soft limit \n" );
4040 printf( "soft limits - current %lld should be %lld \n", my_rlimit.rlim_cur, my_current_rlimit.rlim_cur );
4041 goto test_failed_exit;
4042 }
4043
4044 #if CONFORMANCE_CHANGES_IN_XNU // can't do this check until conformance changes get into xnu
4045 printf( "hard limits - current %lld should be %lld \n", my_rlimit.rlim_max, my_current_rlimit.rlim_max );
4046 if ( my_rlimit.rlim_max != my_current_rlimit.rlim_max ) {
4047 printf( "failed to get/set new RLIMIT_NOFILE hard limit \n" );
4048 goto test_failed_exit;
4049 }
4050 #endif
4051
4052 /*
4053 * A test for a limit that won't fit in a signed 32 bits, a la 5414697
4054 * Note: my_rlimit should still have a valid rlim_max.
4055 */
4056 long long biglim = 2147483649ll; /* Just over 2^31 */
4057 my_rlimit.rlim_cur = biglim;
4058 my_err = setrlimit(RLIMIT_CPU, &my_rlimit);
4059 if (my_err == -1) {
4060 printf("failed to set large limit.\n");
4061 goto test_failed_exit;
4062 }
4063
4064 bzero(&my_rlimit, sizeof(struct rlimit));
4065 my_err = getrlimit(RLIMIT_CPU, &my_rlimit);
4066 if (my_err == -1) {
4067 printf("after setting large value, failed to getrlimit().\n");
4068 goto test_failed_exit;
4069 }
4070
4071 if (my_rlimit.rlim_cur != biglim) {
4072 printf("didn't retrieve large limit.\n");
4073 goto test_failed_exit;
4074 }
4075 }
4076
4077 my_err = 0;
4078 goto test_passed_exit;
4079
4080 test_failed_exit:
4081 my_err = -1;
4082
4083 test_passed_exit:
4084 return( my_err );
4085 }
4086
4087 /* **************************************************************************************************************
4088 * Test getattrlist, getdirentriesattr, setattrlist system calls.
4089 * **************************************************************************************************************
4090 */
4091 struct test_attr_buf {
4092 uint32_t length;
4093 fsobj_type_t obj_type;
4094 fsobj_id_t obj_id;
4095 struct timespec backup_time;
4096 };
4097
4098 typedef struct test_attr_buf test_attr_buf;
4099
4100 int directory_tests( void * the_argp )
4101 {
4102 int my_err, done, found_it, i;
4103 int my_fd = -1;
4104 int is_ufs = 0;
4105 char * my_pathp = NULL;
4106 char * my_bufp = NULL;
4107 char * my_file_namep;
4108 #ifdef __LP64__
4109 unsigned int my_base;
4110 unsigned int my_count;
4111 unsigned int my_new_state;
4112 #else
4113 unsigned long my_base;
4114 unsigned long my_count;
4115 unsigned long my_new_state;
4116 #endif
4117 fsobj_id_t my_obj_id;
4118 struct timespec my_new_backup_time;
4119 struct attrlist my_attrlist;
4120 test_attr_buf my_attr_buf[4];
4121 struct statfs my_statfs_buf;
4122 kern_return_t my_kr;
4123
4124 /* need to know type of file system */
4125 my_err = statfs( &g_target_path[0], &my_statfs_buf );
4126 if ( my_err == -1 ) {
4127 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
4128 goto test_failed_exit;
4129 }
4130 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4131 is_ufs = 1;
4132 }
4133
4134 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE);
4135 if(my_kr != KERN_SUCCESS){
4136 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4137 goto test_failed_exit;
4138 }
4139
4140 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4141 if(my_kr != KERN_SUCCESS){
4142 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4143 goto test_failed_exit;
4144 }
4145
4146 *my_pathp = 0x00;
4147 strcat( my_pathp, &g_target_path[0] );
4148 strcat( my_pathp, "/" );
4149
4150 /* create a test file */
4151 my_err = create_random_name( my_pathp, 1 );
4152 if ( my_err != 0 ) {
4153 goto test_failed_exit;
4154 }
4155
4156 /* get pointer to just the file name */
4157 my_file_namep = strrchr( my_pathp, '/' );
4158 my_file_namep++;
4159
4160 /* check out the test directory */
4161 my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4162 if ( my_fd == -1 ) {
4163 printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4164 goto test_failed_exit;
4165 }
4166
4167 /* test get/setattrlist */
4168 memset( &my_attrlist, 0, sizeof(my_attrlist) );
4169 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4170 my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4171 my_err = getattrlist( my_pathp, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf[0]), 0 );
4172
4173 if ( my_err != 0 ) {
4174 if ( errno == ENOTSUP && is_ufs ) {
4175 /* getattr calls not supported on ufs */
4176 my_err = 0;
4177 goto test_passed_exit;
4178 }
4179 printf( "getattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) );
4180 goto test_failed_exit;
4181 }
4182 /* validate returned data */
4183 if ( my_attr_buf[0].obj_type != VREG ) {
4184 printf( "getattrlist returned incorrect obj_type data. \n" );
4185 goto test_failed_exit;
4186 }
4187
4188 /* set new backup time */
4189 my_obj_id = my_attr_buf[0].obj_id;
4190 my_new_backup_time = my_attr_buf[0].backup_time;
4191 my_new_backup_time.tv_sec += 60;
4192 my_attr_buf[0].backup_time.tv_sec = my_new_backup_time.tv_sec;
4193 my_attrlist.commonattr = (ATTR_CMN_BKUPTIME);
4194 my_err = setattrlist( my_pathp, &my_attrlist, &my_attr_buf[0].backup_time, sizeof(my_attr_buf[0].backup_time), 0 );
4195 if ( my_err != 0 ) {
4196 printf( "setattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) );
4197 goto test_failed_exit;
4198 }
4199
4200 /* validate setattrlist using getdirentriesattr */
4201 close( my_fd );
4202 my_fd = open( &g_target_path[0], (O_RDONLY), 0 );
4203 if ( my_fd == -1 ) {
4204 printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) );
4205 goto test_failed_exit;
4206 }
4207 memset( &my_attrlist, 0, sizeof(my_attrlist) );
4208 memset( &my_attr_buf, 0, sizeof(my_attr_buf) );
4209 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
4210 my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME);
4211 my_count = 4;
4212 my_base = 0;
4213 my_err = getdirentriesattr( my_fd, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf), &my_count,
4214 &my_base, &my_new_state, 0 );
4215 if ( my_err < 0 ) {
4216 printf( "getdirentriesattr call failed. got errno %d - %s. \n", errno, strerror( errno ) );
4217 goto test_failed_exit;
4218 }
4219
4220 found_it = 0;
4221 for ( i = 0; i < my_count; i++ ) {
4222 if ( my_attr_buf[i].obj_id.fid_objno == my_obj_id.fid_objno &&
4223 my_attr_buf[i].obj_id.fid_generation == my_obj_id.fid_generation ) {
4224 found_it = 1;
4225 if ( my_attr_buf[i].backup_time.tv_sec != my_new_backup_time.tv_sec ) {
4226 printf( "setattrlist failed to set backup time. \n" );
4227 goto test_failed_exit;
4228 }
4229 }
4230 }
4231 if ( found_it == 0 ) {
4232 printf( "getdirentriesattr failed to find test file. \n" );
4233 goto test_failed_exit;
4234 }
4235
4236 my_err = 0;
4237 goto test_passed_exit;
4238
4239 test_failed_exit:
4240 if(my_err != 0)
4241 my_err = -1;
4242
4243 test_passed_exit:
4244 if ( my_fd != -1 )
4245 close( my_fd );
4246 if ( my_pathp != NULL ) {
4247 remove( my_pathp );
4248 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4249 }
4250 if ( my_bufp != NULL ) {
4251 vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5));
4252 }
4253 return( my_err );
4254 }
4255
4256 /* **************************************************************************************************************
4257 * Test exchangedata system calls.
4258 * **************************************************************************************************************
4259 */
4260 int exchangedata_test( void * the_argp )
4261 {
4262 int my_err;
4263 int my_fd1 = -1;
4264 int my_fd2 = -1;
4265 char * my_file1_pathp = NULL;
4266 char * my_file2_pathp = NULL;
4267 ssize_t my_result;
4268 char my_buffer[16];
4269 struct statfs my_statfs_buf;
4270 kern_return_t my_kr;
4271
4272 /* need to know type of file system */
4273 my_err = statfs( &g_target_path[0], &my_statfs_buf );
4274 if ( my_err == -1 ) {
4275 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
4276 goto test_failed_exit;
4277 }
4278 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4279 /* ufs does not support exchangedata */
4280 my_err = 0;
4281 goto test_passed_exit;
4282 }
4283
4284 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file1_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4285 if(my_kr != KERN_SUCCESS){
4286 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4287 goto test_failed_exit;
4288 }
4289
4290 *my_file1_pathp = 0x00;
4291 strcat( my_file1_pathp, &g_target_path[0] );
4292 strcat( my_file1_pathp, "/" );
4293
4294 /* create a test file */
4295 my_err = create_random_name( my_file1_pathp, 1 );
4296 if ( my_err != 0 ) {
4297 printf( "create_random_name my_err: %d\n", my_err );
4298 goto test_failed_exit;
4299 }
4300 my_fd1 = open( my_file1_pathp, O_RDWR, 0 );
4301 if ( my_fd1 == -1 ) {
4302 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4303 goto test_failed_exit;
4304 }
4305 my_result = write( my_fd1, "11111111", 8 );
4306 if ( my_result == -1 ) {
4307 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4308 goto test_failed_exit;
4309 }
4310
4311 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file2_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4312 if(my_kr != KERN_SUCCESS){
4313 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4314 goto test_failed_exit;
4315 }
4316
4317 *my_file2_pathp = 0x00;
4318 strcat( my_file2_pathp, &g_target_path[0] );
4319 strcat( my_file2_pathp, "/" );
4320
4321 /* create a test file */
4322 my_err = create_random_name( my_file2_pathp, 1 );
4323 if ( my_err != 0 ) {
4324 printf( "create_random_name my_err: %d\n", my_err );
4325 goto test_failed_exit;
4326 }
4327 my_fd2 = open( my_file2_pathp, O_RDWR, 0 );
4328 if ( my_fd2 == -1 ) {
4329 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4330 goto test_failed_exit;
4331 }
4332 my_result = write( my_fd2, "22222222", 8 );
4333 if ( my_result == -1 ) {
4334 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4335 goto test_failed_exit;
4336 }
4337 close(my_fd1);
4338 my_fd1 = -1;
4339 close(my_fd2);
4340 my_fd2 = -1;
4341
4342 /* test exchangedata */
4343 my_err = exchangedata( my_file1_pathp, my_file2_pathp, 0 );
4344 if ( my_err == -1 ) {
4345 printf( "exchangedata failed with error %d - \"%s\" \n", errno, strerror( errno) );
4346 goto test_failed_exit;
4347 }
4348
4349 /* now validate exchange */
4350 my_fd1 = open( my_file1_pathp, O_RDONLY, 0 );
4351 if ( my_fd1 == -1 ) {
4352 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4353 goto test_failed_exit;
4354 }
4355 bzero( (void *)&my_buffer[0], sizeof(my_buffer) );
4356 my_result = read( my_fd1, &my_buffer[0], 8 );
4357 if ( my_result == -1 ) {
4358 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4359 goto test_failed_exit;
4360 }
4361
4362 if ( memcmp( &my_buffer[0], "22222222", 8 ) != 0 ) {
4363 printf( "exchangedata failed - incorrect data in file \n" );
4364 goto test_failed_exit;
4365 }
4366
4367 my_err = 0;
4368 goto test_passed_exit;
4369
4370 test_failed_exit:
4371 my_err = -1;
4372
4373 test_passed_exit:
4374 if ( my_fd1 != -1 )
4375 close( my_fd1 );
4376 if ( my_file1_pathp != NULL ) {
4377 remove( my_file1_pathp );
4378 vm_deallocate(mach_task_self(), (vm_address_t)my_file1_pathp, PATH_MAX);
4379 }
4380 if ( my_fd2 != -1 )
4381 close( my_fd2 );
4382 if ( my_file2_pathp != NULL ) {
4383 remove( my_file2_pathp );
4384 vm_deallocate(mach_task_self(), (vm_address_t)my_file2_pathp, PATH_MAX);
4385 }
4386 return( my_err );
4387 }
4388
4389
4390 /* **************************************************************************************************************
4391 * Test searchfs system calls.
4392 * **************************************************************************************************************
4393 */
4394
4395 struct packed_name_attr {
4396 u_int32_t size; /* Of the remaining fields */
4397 struct attrreference ref; /* Offset/length of name itself */
4398 char name[ PATH_MAX ];
4399 };
4400
4401 struct packed_attr_ref {
4402 u_int32_t size; /* Of the remaining fields */
4403 struct attrreference ref; /* Offset/length of attr itself */
4404 };
4405
4406 struct packed_result {
4407 u_int32_t size; /* Including size field itself */
4408 attrreference_t obj_name;
4409 struct fsobj_id obj_id;
4410 struct timespec obj_create_time;
4411 char room_for_name[ 64 ];
4412 };
4413 typedef struct packed_result packed_result;
4414 typedef struct packed_result * packed_result_p;
4415
4416 #define MAX_MATCHES 10
4417 #define MAX_EBUSY_RETRIES 5
4418
4419 int searchfs_test( void * the_argp )
4420 {
4421 int my_err, my_items_found = 0, my_ebusy_count;
4422 char * my_pathp = NULL;
4423 unsigned long my_matches;
4424 unsigned long my_search_options;
4425 struct fssearchblock my_search_blk;
4426 struct attrlist my_return_list;
4427 struct searchstate my_search_state;
4428 struct packed_name_attr my_info1;
4429 struct packed_attr_ref my_info2;
4430 packed_result my_result_buffer[ MAX_MATCHES ];
4431 struct statfs my_statfs_buf;
4432 kern_return_t my_kr;
4433
4434 /* need to know type of file system */
4435 my_err = statfs( &g_target_path[0], &my_statfs_buf );
4436 if ( my_err == -1 ) {
4437 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) );
4438 goto test_failed_exit;
4439 }
4440 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) {
4441 /* ufs does not support exchangedata */
4442 my_err = 0;
4443 goto test_passed_exit;
4444 }
4445
4446 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
4447 if(my_kr != KERN_SUCCESS){
4448 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4449 goto test_failed_exit;
4450 }
4451
4452 *my_pathp = 0x00;
4453 strcat( my_pathp, &g_target_path[0] );
4454 strcat( my_pathp, "/" );
4455
4456 /* create test files */
4457 my_err = create_file_with_name( my_pathp, "foo", 0 );
4458 if ( my_err < 0 ) {
4459 printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4460 goto test_failed_exit;
4461 }
4462
4463 my_err = create_file_with_name( my_pathp, "foobar", 0 );
4464 if ( my_err < 0 ) {
4465 printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4466 goto test_failed_exit;
4467 }
4468
4469 my_err = create_file_with_name( my_pathp, "foofoo", 0 );
4470 if ( my_err < 0 ) {
4471 printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4472 goto test_failed_exit;
4473 }
4474
4475 my_err = create_file_with_name( my_pathp, "xxxfoo", 0 );
4476 if ( my_err < 0 ) {
4477 printf( "failed to create a test file name in \"%s\" \n", my_pathp );
4478 goto test_failed_exit;
4479 }
4480
4481 /* EBUSY count updated below the catalogue_changed label */
4482 my_ebusy_count = 0;
4483
4484 catalogue_changed:
4485 /* search target volume for all file system objects with "foo" in the name */
4486 /* Set up the attributes we're searching on. */
4487 my_items_found = 0; /* Set this here in case we're completely restarting */
4488 my_search_blk.searchattrs.bitmapcount = ATTR_BIT_MAP_COUNT;
4489 my_search_blk.searchattrs.reserved = 0;
4490 my_search_blk.searchattrs.commonattr = ATTR_CMN_NAME;
4491 my_search_blk.searchattrs.volattr = 0;
4492 my_search_blk.searchattrs.dirattr = 0;
4493 my_search_blk.searchattrs.fileattr = 0;
4494 my_search_blk.searchattrs.forkattr = 0;
4495
4496 /* Set up the attributes we want for all returned matches. */
4497 /* Why is returnattrs a pointer instead of an embedded struct? */
4498 my_search_blk.returnattrs = &my_return_list;
4499 my_return_list.bitmapcount = ATTR_BIT_MAP_COUNT;
4500 my_return_list.reserved = 0;
4501 my_return_list.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJID | ATTR_CMN_CRTIME;
4502 my_return_list.volattr = 0;
4503 my_return_list.dirattr = 0;
4504 my_return_list.fileattr = 0;
4505 my_return_list.forkattr = 0;
4506
4507 /* Allocate a buffer for returned matches */
4508 my_search_blk.returnbuffer = my_result_buffer;
4509 my_search_blk.returnbuffersize = sizeof(my_result_buffer);
4510
4511 /* Pack the searchparams1 into a buffer */
4512 /* NOTE: A name appears only in searchparams1 */
4513 strcpy( my_info1.name, "foo" );
4514 my_info1.ref.attr_dataoffset = sizeof(struct attrreference);
4515 my_info1.ref.attr_length = strlen(my_info1.name) + 1;
4516 my_info1.size = sizeof(struct attrreference) + my_info1.ref.attr_length;
4517 my_search_blk.searchparams1 = &my_info1;
4518 my_search_blk.sizeofsearchparams1 = my_info1.size + sizeof(u_int32_t);
4519
4520 /* Pack the searchparams2 into a buffer */
4521 my_info2.size = sizeof(struct attrreference);
4522 my_info2.ref.attr_dataoffset = sizeof(struct attrreference);
4523 my_info2.ref.attr_length = 0;
4524 my_search_blk.searchparams2 = &my_info2;
4525 my_search_blk.sizeofsearchparams2 = sizeof(my_info2);
4526
4527 /* Maximum number of matches we want */
4528 my_search_blk.maxmatches = MAX_MATCHES;
4529
4530 /* Maximum time to search, per call */
4531 my_search_blk.timelimit.tv_sec = 1;
4532 my_search_blk.timelimit.tv_usec = 0;
4533
4534 my_search_options = (SRCHFS_START | SRCHFS_MATCHPARTIALNAMES |
4535 SRCHFS_MATCHFILES | SRCHFS_MATCHDIRS);
4536 do {
4537 char * my_end_ptr;
4538 char * my_ptr;
4539 int i;
4540
4541 my_err = searchfs( my_pathp, &my_search_blk, &my_matches, 0, my_search_options, &my_search_state );
4542 if ( my_err == -1 )
4543 my_err = errno;
4544 if ( (my_err == 0 || my_err == EAGAIN) && my_matches > 0 ) {
4545 /* Unpack the results */
4546 // printf("my_matches %d \n", my_matches);
4547 my_ptr = (char *) &my_result_buffer[0];
4548 my_end_ptr = (my_ptr + sizeof(my_result_buffer));
4549 for ( i = 0; i < my_matches; ++i ) {
4550 packed_result_p my_result_p = (packed_result_p) my_ptr;
4551 char * my_name_p;
4552
4553 /* see if we foound all our test files */
4554 my_name_p = (((char *)(&my_result_p->obj_name)) + my_result_p->obj_name.attr_dataoffset);
4555 if ( memcmp( my_name_p, "foo", 3 ) == 0 ||
4556 memcmp( my_name_p, "foobar", 6 ) == 0 ||
4557 memcmp( my_name_p, "foofoo", 6 ) == 0 ||
4558 memcmp( my_name_p, "xxxfoo", 6 ) == 0 ) {
4559 my_items_found++;
4560 }
4561 #if DEBUG
4562 printf("obj_name \"%.*s\" \n",
4563 (int) my_result_p->obj_name.attr_length,
4564 (((char *)(&my_result_p->obj_name)) +
4565 my_result_p->obj_name.attr_dataoffset));
4566 printf("size %d fid_objno %d fid_generation %d tv_sec 0x%02LX \n",
4567 my_result_p->size, my_result_p->obj_id.fid_objno,
4568 my_result_p->obj_id.fid_generation,
4569 my_result_p->obj_create_time.tv_sec);
4570 #endif
4571 my_ptr = (my_ptr + my_result_p->size);
4572 if (my_ptr > my_end_ptr)
4573 break;
4574 }
4575 }
4576
4577 /* EBUSY indicates catalogue change; retry a few times. */
4578 if ((my_err == EBUSY) && (my_ebusy_count++ < MAX_EBUSY_RETRIES)) {
4579 goto catalogue_changed;
4580 }
4581 if ( !(my_err == 0 || my_err == EAGAIN) ) {
4582 printf( "searchfs failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4583 }
4584 my_search_options &= ~SRCHFS_START;
4585 } while ( my_err == EAGAIN );
4586
4587 if ( my_items_found < 4 ) {
4588 printf( "searchfs failed to find all test files \n" );
4589 goto test_failed_exit;
4590 }
4591
4592 my_err = 0;
4593 goto test_passed_exit;
4594
4595 test_failed_exit:
4596 my_err = -1;
4597
4598 test_passed_exit:
4599 if ( my_pathp != NULL ) {
4600 char * my_ptr = (my_pathp + strlen( my_pathp ));
4601 strcat( my_pathp, "foo" );
4602 remove( my_pathp );
4603 *my_ptr = 0x00;
4604 strcat( my_pathp, "foobar" );
4605 remove( my_pathp );
4606 *my_ptr = 0x00;
4607 strcat( my_pathp, "foofoo" );
4608 remove( my_pathp );
4609 *my_ptr = 0x00;
4610 strcat( my_pathp, "xxxfoo" );
4611 remove( my_pathp );
4612 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
4613 }
4614 return( my_err );
4615 }
4616
4617
4618 #define AIO_TESTS_BUFFER_SIZE (1024 * 4000)
4619 #define AIO_TESTS_OUR_COUNT 5
4620 /* **************************************************************************************************************
4621 * Test aio_error, aio_read, aio_return, aio_suspend, aio_write, fcntl system calls.
4622 * **************************************************************************************************************
4623 */
4624 int aio_tests( void * the_argp )
4625 {
4626 #if !TARGET_OS_EMBEDDED
4627 int my_err, i;
4628 char * my_pathp;
4629 struct aiocb * my_aiocbp;
4630 ssize_t my_result;
4631 struct timespec my_timeout;
4632 int my_fd_list[ AIO_TESTS_OUR_COUNT ];
4633 char * my_buffers[ AIO_TESTS_OUR_COUNT ];
4634 struct aiocb * my_aiocb_list[ AIO_TESTS_OUR_COUNT ];
4635 struct aiocb my_aiocbs[ AIO_TESTS_OUR_COUNT ];
4636 char * my_file_paths[ AIO_TESTS_OUR_COUNT ];
4637 kern_return_t my_kr;
4638
4639 /* set up to have the ability to fire off up to AIO_TESTS_OUR_COUNT async IOs at once */
4640 memset( &my_fd_list[0], 0xFF, sizeof( my_fd_list ) );
4641 memset( &my_buffers[0], 0x00, sizeof( my_buffers ) );
4642 memset( &my_aiocb_list[0], 0x00, sizeof( my_aiocb_list ) );
4643 memset( &my_file_paths[0], 0x00, sizeof( my_file_paths ) );
4644 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4645 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_buffers[ i ], AIO_TESTS_BUFFER_SIZE, VM_FLAGS_ANYWHERE);
4646 if(my_kr != KERN_SUCCESS){
4647 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4648 goto test_failed_exit;
4649 }
4650
4651 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file_paths[ i ], PATH_MAX, VM_FLAGS_ANYWHERE);
4652 if(my_kr != KERN_SUCCESS){
4653 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
4654 goto test_failed_exit;
4655 }
4656
4657 my_pathp = my_file_paths[ i ];
4658 *my_pathp = 0x00;
4659 strcat( my_pathp, &g_target_path[0] );
4660 strcat( my_pathp, "/" );
4661
4662 /* create a test file */
4663 my_err = create_random_name( my_pathp, 1 );
4664 if ( my_err != 0 ) {
4665 goto test_failed_exit;
4666 }
4667 my_fd_list[ i ] = open( my_pathp, O_RDWR, 0 );
4668 if ( my_fd_list[ i ] <= 0 ) {
4669 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4670 goto test_failed_exit;
4671 }
4672
4673 my_aiocbp = &my_aiocbs[ i ];
4674 my_aiocb_list[ i ] = my_aiocbp;
4675 memset( my_aiocbp, 0x00, sizeof( *my_aiocbp ) );
4676 my_aiocbp->aio_fildes = my_fd_list[ i ];
4677 my_aiocbp->aio_buf = (char *) my_buffers[ i ];
4678 my_aiocbp->aio_nbytes = 1024;
4679 my_aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; // no signals at completion;
4680 my_aiocbp->aio_sigevent.sigev_signo = 0;
4681 }
4682
4683 /* test direct IO (F_NOCACHE) and aio_write */
4684 my_err = fcntl( my_fd_list[ 0 ], F_NOCACHE, 1 );
4685 if ( my_err != 0 ) {
4686 printf( "malloc failed with error %d - \"%s\" \n", errno, strerror( errno) );
4687 goto test_failed_exit;
4688 }
4689
4690 my_aiocbp = &my_aiocbs[ 0 ];
4691 my_aiocbp->aio_fildes = my_fd_list[ 0 ];
4692 my_aiocbp->aio_offset = 4096;
4693 my_aiocbp->aio_buf = my_buffers[ 0 ];
4694 my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE;
4695 my_aiocbp->aio_reqprio = 0;
4696 my_aiocbp->aio_sigevent.sigev_notify = 0;
4697 my_aiocbp->aio_sigevent.sigev_signo = 0;
4698 my_aiocbp->aio_sigevent.sigev_value.sival_int = 0;
4699 my_aiocbp->aio_sigevent.sigev_notify_function = NULL;
4700 my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL;
4701 my_aiocbp->aio_lio_opcode = 0;
4702
4703 /* write some data */
4704 memset( my_buffers[ 0 ], 'j', AIO_TESTS_BUFFER_SIZE );
4705 my_err = aio_write( my_aiocbp );
4706 if ( my_err != 0 ) {
4707 printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4708 goto test_failed_exit;
4709 }
4710
4711 while ( 1 ) {
4712 my_err = aio_error( my_aiocbp );
4713 if ( my_err == EINPROGRESS ) {
4714 /* wait for IO to complete */
4715 sleep( 1 );
4716 continue;
4717 }
4718 else if ( my_err == 0 ) {
4719 ssize_t my_result;
4720 my_result = aio_return( my_aiocbp );
4721 break;
4722 }
4723 else {
4724 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4725 goto test_failed_exit;
4726 }
4727 } /* while loop */
4728
4729 /* read some data */
4730 memset( my_buffers[ 0 ], 'x', AIO_TESTS_BUFFER_SIZE );
4731 my_err = aio_read( my_aiocbp );
4732
4733 while ( 1 ) {
4734 my_err = aio_error( my_aiocbp );
4735 if ( my_err == EINPROGRESS ) {
4736 /* wait for IO to complete */
4737 sleep( 1 );
4738 continue;
4739 }
4740 else if ( my_err == 0 ) {
4741 ssize_t my_result;
4742 my_result = aio_return( my_aiocbp );
4743
4744 if ( *(my_buffers[ 0 ]) != 'j' || *(my_buffers[ 0 ] + AIO_TESTS_BUFFER_SIZE - 1) != 'j' ) {
4745 printf( "aio_read or aio_write failed - wrong data read \n" );
4746 goto test_failed_exit;
4747 }
4748 break;
4749 }
4750 else {
4751 printf( "aio_read failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4752 goto test_failed_exit;
4753 }
4754 } /* while loop */
4755
4756 /* test aio_fsync */
4757 close( my_fd_list[ 0 ] );
4758 my_fd_list[ 0 ] = open( my_pathp, O_RDWR, 0 );
4759 if ( my_fd_list[ 0 ] == -1 ) {
4760 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4761 goto test_failed_exit;
4762 }
4763
4764 my_aiocbp = &my_aiocbs[ 0 ];
4765 my_aiocbp->aio_fildes = my_fd_list[ 0 ];
4766 my_aiocbp->aio_offset = 0;
4767 my_aiocbp->aio_buf = my_buffers[ 0 ];
4768 my_aiocbp->aio_nbytes = 1024;
4769 my_aiocbp->aio_reqprio = 0;
4770 my_aiocbp->aio_sigevent.sigev_notify = 0;
4771 my_aiocbp->aio_sigevent.sigev_signo = 0;
4772 my_aiocbp->aio_sigevent.sigev_value.sival_int = 0;
4773 my_aiocbp->aio_sigevent.sigev_notify_function = NULL;
4774 my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL;
4775 my_aiocbp->aio_lio_opcode = 0;
4776
4777 /* write some data */
4778 memset( my_buffers[ 0 ], 'e', 1024 );
4779 my_err = aio_write( my_aiocbp );
4780 if ( my_err != 0 ) {
4781 printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4782 goto test_failed_exit;
4783 }
4784 while ( 1 ) {
4785 my_err = aio_error( my_aiocbp );
4786 if ( my_err == EINPROGRESS ) {
4787 /* wait for IO to complete */
4788 sleep( 1 );
4789 continue;
4790 }
4791 else if ( my_err == 0 ) {
4792 ssize_t my_result;
4793 my_result = aio_return( my_aiocbp );
4794 break;
4795 }
4796 else {
4797 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4798 goto test_failed_exit;
4799 }
4800 } /* while loop */
4801
4802 my_err = aio_fsync( O_SYNC, my_aiocbp );
4803 if ( my_err != 0 ) {
4804 printf( "aio_fsync failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4805 goto test_failed_exit;
4806 }
4807 while ( 1 ) {
4808 my_err = aio_error( my_aiocbp );
4809 if ( my_err == EINPROGRESS ) {
4810 /* wait for IO to complete */
4811 sleep( 1 );
4812 continue;
4813 }
4814 else if ( my_err == 0 ) {
4815 aio_return( my_aiocbp );
4816 break;
4817 }
4818 else {
4819 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) );
4820 goto test_failed_exit;
4821 }
4822 } /* while loop */
4823
4824 /* validate write */
4825 memset( my_buffers[ 0 ], 0x20, 16 );
4826 lseek( my_fd_list[ 0 ], 0, SEEK_SET );
4827 my_result = read( my_fd_list[ 0 ], my_buffers[ 0 ], 16);
4828 if ( my_result == -1 ) {
4829 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4830 goto test_failed_exit;
4831 }
4832 if ( *(my_buffers[ 0 ]) != 'e' || *(my_buffers[ 0 ] + 16 - 1) != 'e' ) {
4833 printf( "aio_fsync or aio_write failed - wrong data read \n" );
4834 goto test_failed_exit;
4835 }
4836
4837 /* test aio_suspend and lio_listio */
4838 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4839 memset( my_buffers[ i ], 'a', AIO_TESTS_BUFFER_SIZE );
4840 my_aiocbp = &my_aiocbs[ i ];
4841 my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE;
4842 my_aiocbp->aio_lio_opcode = LIO_WRITE;
4843 }
4844 my_err = lio_listio( LIO_NOWAIT, my_aiocb_list, AIO_TESTS_OUR_COUNT, NULL );
4845 if ( my_err != 0 ) {
4846 printf( "lio_listio call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4847 goto test_failed_exit;
4848 }
4849
4850 my_timeout.tv_sec = 1;
4851 my_timeout.tv_nsec = 0;
4852 my_err = aio_suspend( (const struct aiocb *const*) my_aiocb_list, AIO_TESTS_OUR_COUNT, &my_timeout );
4853 if ( my_err != 0 ) {
4854 printf( "aio_suspend call failed with error %d - \"%s\" \n", errno, strerror( errno) );
4855 goto test_failed_exit;
4856 }
4857
4858 /* test aio_cancel */
4859 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4860 my_aiocbp = &my_aiocbs[ i ];
4861 my_err = aio_cancel( my_aiocbp->aio_fildes, my_aiocbp );
4862 if ( my_err != AIO_ALLDONE && my_err != AIO_CANCELED && my_err != AIO_NOTCANCELED ) {
4863 printf( "aio_cancel failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
4864 goto test_failed_exit;
4865 }
4866 }
4867
4868 my_err = 0;
4869 goto test_passed_exit;
4870
4871 test_failed_exit:
4872 my_err = -1;
4873
4874 test_passed_exit:
4875 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) {
4876 if ( my_fd_list[ i ] != -1 ) {
4877 close( my_fd_list[ i ] );
4878 my_fd_list[ i ] = -1;
4879 }
4880 if ( my_file_paths[ i ] != NULL ) {
4881 remove( my_file_paths[ i ] );
4882 vm_deallocate(mach_task_self(), (vm_address_t)my_file_paths[ i ], PATH_MAX);
4883 my_file_paths[ i ] = NULL;
4884 }
4885 if ( my_buffers[ i ] != NULL ) {
4886 vm_deallocate(mach_task_self(), (vm_address_t)my_buffers[ i ], AIO_TESTS_BUFFER_SIZE);
4887 my_buffers[ i ] = NULL;
4888 }
4889 }
4890 return( my_err );
4891 #else
4892 printf( "\t--> Not supported on EMBEDDED TARGET\n" );
4893 return 0;
4894 #endif
4895 }
4896
4897
4898 /* **************************************************************************************************************
4899 * Test msgctl, msgget, msgrcv, msgsnd system calls.
4900 * **************************************************************************************************************
4901 */
4902 int message_queue_tests( void * the_argp )
4903 {
4904 #if !TARGET_OS_EMBEDDED
4905 int my_err;
4906 int my_msg_queue_id = -1;
4907 ssize_t my_result;
4908 struct msqid_ds my_msq_ds;
4909 struct testing_msq_message {
4910 long msq_type;
4911 char msq_buffer[ 32 ];
4912 } my_msg;
4913
4914 /* get a message queue established for our use */
4915 my_msg_queue_id = msgget( IPC_PRIVATE, (IPC_CREAT | IPC_EXCL | IPC_R | IPC_W) );
4916 if ( my_msg_queue_id == -1 ) {
4917 printf( "msgget failed with errno %d - %s \n", errno, strerror( errno ) );
4918 goto test_failed_exit;
4919 }
4920
4921 /* get some stats on our message queue */
4922 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
4923 if ( my_err == -1 ) {
4924 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
4925 goto test_failed_exit;
4926 }
4927 if ( my_msq_ds.msg_perm.cuid != geteuid( ) ) {
4928 printf( "msgctl IPC_STAT failed to get correct creator uid \n" );
4929 goto test_failed_exit;
4930 }
4931 if ( (my_msq_ds.msg_perm.mode & (IPC_R | IPC_W)) == 0 ) {
4932 printf( "msgctl IPC_STAT failed to get correct mode \n" );
4933 goto test_failed_exit;
4934 }
4935
4936 /* put a message into our queue */
4937 my_msg.msq_type = 1;
4938 strcpy( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" );
4939 my_err = msgsnd( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0 );
4940 if ( my_err == -1 ) {
4941 printf( "msgsnd failed with errno %d - %s \n", errno, strerror( errno ) );
4942 goto test_failed_exit;
4943 }
4944
4945 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
4946 if ( my_err == -1 ) {
4947 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
4948 goto test_failed_exit;
4949 }
4950 if ( my_msq_ds.msg_qnum != 1 ) {
4951 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
4952 goto test_failed_exit;
4953 }
4954
4955 /* pull message off the queue */
4956 bzero( (void *)&my_msg, sizeof( my_msg ) );
4957 my_result = msgrcv( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0, 0 );
4958 if ( my_result == -1 ) {
4959 printf( "msgrcv failed with errno %d - %s \n", errno, strerror( errno ) );
4960 goto test_failed_exit;
4961 }
4962 if ( my_result != sizeof( my_msg.msq_buffer ) ) {
4963 printf( "msgrcv failed to return the correct number of bytes in our buffer \n" );
4964 goto test_failed_exit;
4965 }
4966 if ( strcmp( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ) != 0 ) {
4967 printf( "msgrcv failed to get the correct message \n" );
4968 goto test_failed_exit;
4969 }
4970
4971 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds );
4972 if ( my_err == -1 ) {
4973 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) );
4974 goto test_failed_exit;
4975 }
4976 if ( my_msq_ds.msg_qnum != 0 ) {
4977 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
4978 goto test_failed_exit;
4979 }
4980
4981 /* tear down the message queue */
4982 my_err = msgctl( my_msg_queue_id, IPC_RMID, NULL );
4983 if ( my_err == -1 ) {
4984 printf( "msgctl IPC_RMID failed with errno %d - %s \n", errno, strerror( errno ) );
4985 goto test_failed_exit;
4986 }
4987 my_msg_queue_id = -1;
4988
4989 my_err = 0;
4990 goto test_passed_exit;
4991
4992 test_failed_exit:
4993 my_err = -1;
4994
4995 test_passed_exit:
4996 if ( my_msg_queue_id != -1 ) {
4997 msgctl( my_msg_queue_id, IPC_RMID, NULL );
4998 }
4999 return( my_err );
5000 #else
5001 printf( "\t--> Not supported on EMBEDDED TARGET \n" );
5002 return 0;
5003 #endif
5004 }
5005
5006
5007
5008 /* **************************************************************************************************************
5009 * Test execution from data and stack areas.
5010 * **************************************************************************************************************
5011 */
5012 int data_exec_tests( void * the_argp )
5013 {
5014 int my_err = 0;
5015 int arch, bits;
5016 posix_spawnattr_t attrp;
5017 char *argv[] = { "helpers/data_exec32nonxspawn", NULL };
5018
5019 int my_pid, my_status, ret;
5020
5021 if ((arch = get_architecture()) == -1) {
5022 printf("data_exec_test: couldn't determine architecture\n");
5023 goto test_failed_exit;
5024 }
5025
5026 bits = get_bits();
5027
5028 /*
5029 * If the machine is 64-bit capable, run both the 32 and 64 bit versions of the test.
5030 * Otherwise, just run the 32-bit version.
5031 */
5032
5033 if (arch == INTEL) {
5034 if (bits == 64) {
5035 if (system("arch -arch x86_64 helpers/data_exec") != 0) {
5036 printf("data_exec-x86_64 failed\n");
5037 goto test_failed_exit;
5038 }
5039 }
5040
5041 if (system("arch -arch i386 helpers/data_exec") != 0) {
5042 printf("data_exec-i386 failed\n");
5043 goto test_failed_exit;
5044 }
5045
5046 posix_spawnattr_init(&attrp);
5047 posix_spawnattr_setflags(&attrp, _POSIX_SPAWN_ALLOW_DATA_EXEC );
5048 ret = posix_spawn(&my_pid, "helpers/data_exec32nonxspawn", NULL, &attrp, argv, NULL);
5049 if (ret) {
5050 printf("data_exec-i386 failed in posix_spawn %s\n", strerror(errno));
5051 goto test_failed_exit;
5052 }
5053 ret = wait4(my_pid, &my_status, 0, NULL);
5054 if (ret == -1) {
5055 printf("data_exec-i386 wait4 failed with errno %d - %s\n", errno, strerror(errno));
5056 goto test_failed_exit;
5057 }
5058 if (WEXITSTATUS(my_status) != 0) {
5059 printf("data_exec-i386 _POSIX_SPAWN_ALLOW_DATA_EXEC failed\n");
5060 goto test_failed_exit;
5061 }
5062 }
5063
5064 /* Add new architectures here similar to the above. */
5065
5066 goto test_passed_exit;
5067
5068 test_failed_exit:
5069 my_err = -1;
5070
5071 test_passed_exit:
5072 return my_err;
5073 }
5074
5075
5076 #if TEST_SYSTEM_CALLS
5077
5078 /* **************************************************************************************************************
5079 * Test xxxxxxxxx system calls.
5080 * **************************************************************************************************************
5081 */
5082 int sample_test( void * the_argp )
5083 {
5084 int my_err;
5085 int my_fd = -1;
5086 char * my_pathp = NULL;
5087 kern_return_t my_kr;
5088
5089 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
5090 if(my_kr != KERN_SUCCESS){
5091 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
5092 goto test_failed_exit;
5093 }
5094
5095 *my_pathp = 0x00;
5096 strcat( my_pathp, &g_target_path[0] );
5097 strcat( my_pathp, "/" );
5098
5099 /* create a test file */
5100 my_err = create_random_name( my_pathp, 1 );
5101 if ( my_err != 0 ) {
5102 goto test_failed_exit;
5103 }
5104
5105 /* add your test code here... */
5106
5107
5108 my_err = 0;
5109 goto test_passed_exit;
5110
5111 test_failed_exit:
5112 my_err = -1;
5113
5114 test_passed_exit:
5115 if ( my_fd != -1 )
5116 close( my_fd );
5117 if ( my_pathp != NULL ) {
5118 remove( my_pathp );
5119 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
5120 }
5121 return( my_err );
5122 }
5123
5124 #endif