5 * Created by Jerry Cottingham on 3/25/05.
6 * Copyright 2008 Apple Inc. All rights reserved.
11 #include <sys/ipc.h> /* for message queue tests */
12 #include <sys/msg.h> /* for message queue tests */
13 #include <sys/syscall.h> /* for get / settid */
14 #include <sys/sysctl.h> /* for determining hw */
15 #include <sys/kas_info.h> /* for kas_info() */
16 #include <AvailabilityMacros.h> /* for determination of Mac OS X version (tiger, leopard, etc.) */
17 #include <libkern/OSByteOrder.h> /* for OSSwap32() */
18 #include <mach/mach.h>
21 extern char g_target_path
[ PATH_MAX
];
22 extern int g_skip_setuid_tests
;
23 extern int g_is_single_user
;
26 void print_acct_debug_strings( char * my_ac_comm
);
29 #if TEST_SYSTEM_CALLS /* system calls to do */
30 "reboot", /* 55 = reboot */
31 "revoke", /* 56 = revoke */
32 "sbrk", /* 69 = sbrk */
33 "sstk", /* 70 = sstk */
34 "mount", /* 167 = mount */
35 "unmount", /* 159 = unmount */
36 "undelete", /* 205 = undelete */
37 "watchevent", /* 231 = watchevent */
38 "waitevent", /* 232 = waitevent */
39 "modwatch", /* 233 = modwatch */
40 "fsctl", /* 242 = fsctl */
41 "initgroups", /* 243 = initgroups */
42 "semsys", /* 251 = semsys */
43 "semconfig", /* 257 = semconfig */
44 "msgsys", /* 252 = msgsys */
45 "shmsys", /* 253 = shmsys */
46 "load_shared_file", /* 296 = load_shared_file */
47 "reset_shared_file", /* 297 = reset_shared_file */
48 "new_system_shared_regions", /* 298 = new_system_shared_regions */
49 "shared_region_map_file_np", /* 299 = shared_region_map_file_np */
50 "shared_region_make_private_np", /* 300 = shared_region_make_private_np */
51 "__pthread_kill", /* 328 = __pthread_kill */
52 "pthread_sigmask", /* 329 = pthread_sigmask */
53 "__disable_threadsignal", /* 331 = __disable_threadsignal */
54 "__pthread_markcancel", /* 332 = __pthread_markcancel */
55 "__pthread_canceled", /* 333 = __pthread_canceled */
56 "__semwait_signal", /* 334 = __semwait_signal */
57 "audit", /* 350 = audit */
58 "auditon", /* 351 = auditon */
59 "getaudit", /* 355 = getaudit */
60 "setaudit", /* 356 = setaudit */
61 "getaudit_addr", /* 357 = getaudit_addr */
62 "setaudit_addr", /* 358 = setaudit_addr */
63 "auditctl", /* 359 = auditctl */
66 /* **************************************************************************************************************
67 * Test the syscall system call.
68 * **************************************************************************************************************
70 int syscall_test( void * the_argp
)
77 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
78 if(my_kr
!= KERN_SUCCESS
){
79 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
80 goto test_failed_exit
;
84 strcpy( my_pathp
, &g_target_path
[0] );
85 strcat( my_pathp
, "/" );
87 /* create a test file */
88 my_err
= create_random_name( my_pathp
, 1 );
90 goto test_failed_exit
;
93 /* use an indirect system call to open our test file.
94 * I picked open since it uses a path pointer which grows to 64 bits in an LP64 environment.
96 my_fd
= syscall( SYS_open
, my_pathp
, (O_RDWR
| O_EXCL
), 0 );
98 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
99 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
100 goto test_failed_exit
;
104 goto test_passed_exit
;
112 if ( my_pathp
!= NULL
) {
114 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
119 /* **************************************************************************************************************
120 * Test fork wait4, and exit system calls.
121 * **************************************************************************************************************
123 int fork_wait4_exit_test( void * the_argp
)
125 int my_err
, my_status
;
126 pid_t my_pid
, my_wait_pid
;
127 struct rusage my_usage
;
129 /* spin off another process */
131 if ( my_pid
== -1 ) {
132 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
135 else if ( my_pid
== 0 ) {
138 /* child process does very little then exits */
139 my_err
= stat( &g_target_path
[0], &my_sb
);
141 printf( "stat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
142 printf( "\t path we stated \"%s\" \n", &g_target_path
[0] );
148 /* parent process waits for child to exit */
149 my_wait_pid
= wait4( my_pid
, &my_status
, 0, &my_usage
);
150 if ( my_wait_pid
== -1 ) {
151 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
155 /* wait4 should return our child's pid when it exits */
156 if ( my_wait_pid
!= my_pid
) {
157 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid
, my_pid
);
161 /* kind of just guessing on these values so if this fails we should take a closer
162 * look at the returned rusage structure.
164 if ( my_usage
.ru_utime
.tv_sec
> 1 || my_usage
.ru_stime
.tv_sec
> 1 ||
165 my_usage
.ru_majflt
> 1000 || my_usage
.ru_msgsnd
> 100 ) {
166 printf( "wait4 returned an odd looking rusage structure \n" );
170 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) == 44 ) {
173 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status
);
180 /* **************************************************************************************************************
181 * Test fsync, ftruncate, lseek, pread, pwrite, read, readv, truncate, write, writev system calls.
182 * **************************************************************************************************************
184 int read_write_test( void * the_argp
)
188 char * my_pathp
= NULL
;
189 char * my_bufp
= NULL
;
191 off_t my_current_offset
;
192 struct iovec my_iovs
[2];
196 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
197 if(my_kr
!= KERN_SUCCESS
){
198 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
199 goto test_failed_exit
;
202 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_bufp
, MY_BUFFER_SIZE
, VM_FLAGS_ANYWHERE
);
203 if(my_kr
!= KERN_SUCCESS
){
204 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
205 goto test_failed_exit
;
209 strcat( my_pathp
, &g_target_path
[0] );
210 strcat( my_pathp
, "/" );
212 /* create a test file */
213 my_err
= create_random_name( my_pathp
, 1 );
215 goto test_failed_exit
;
218 my_fd
= open( my_pathp
, O_RDONLY
, 0 );
220 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
221 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
222 goto test_failed_exit
;
225 /* should get EOF since the file is empty at this point */
226 my_result
= read( my_fd
, my_bufp
, 10);
227 if ( my_result
== -1 ) {
228 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
229 goto test_failed_exit
;
231 if ( my_result
!= 0 ) {
232 if ( sizeof( ssize_t
) > sizeof( int ) ) {
233 printf( "read call failed - should have read 0 bytes on empty file - read %ld \n", (long int) my_result
);
236 printf( "read call failed - should have read 0 bytes on empty file - read %d \n", (int) my_result
);
238 goto test_failed_exit
;
241 /* this write should fail since we opened for read only */
242 my_result
= write( my_fd
, my_bufp
, 10 );
244 if ( my_result
!= -1 ) {
245 if ( sizeof( ssize_t
) > sizeof( int ) ) {
246 printf( "write should have failed for read only fd - %ld \n", (long int) my_result
);
249 printf( "write should have failed for read only fd - %d \n", (int) my_result
);
251 goto test_failed_exit
;
253 if ( my_err
!= EBADF
) {
254 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
255 printf( "should have failed with EBADF error %d \n", EBADF
);
256 goto test_failed_exit
;
259 /* now really write some data */
261 my_fd
= open( my_pathp
, O_RDWR
, 0 );
263 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
264 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
265 goto test_failed_exit
;
268 memset( my_bufp
, 'j', MY_BUFFER_SIZE
);
269 my_result
= write( my_fd
, my_bufp
, MY_BUFFER_SIZE
);
270 if ( my_result
== -1 ) {
271 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
272 goto test_failed_exit
;
274 if ( my_result
!= MY_BUFFER_SIZE
) {
275 printf( "write failed to write out all the data \n" );
276 goto test_failed_exit
;
279 /* push data to disk */
280 my_err
= fsync( my_fd
);
281 if ( my_err
== -1 ) {
282 printf( "fsync failed with errno %d - %s \n", errno
, strerror( errno
) );
283 goto test_failed_exit
;
286 /* now verify the write worked OK using readv */
287 lseek( my_fd
, 0, SEEK_SET
);
288 bzero( (void *)my_bufp
, MY_BUFFER_SIZE
);
289 my_iovs
[0].iov_base
= my_bufp
;
290 my_iovs
[0].iov_len
= 16;
291 my_iovs
[1].iov_base
= (my_bufp
+ MY_BUFFER_SIZE
- 16) ;
292 my_iovs
[1].iov_len
= 16;
294 my_result
= readv( my_fd
, &my_iovs
[0], 2 );
295 if ( my_result
== -1 ) {
296 printf( "readv call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
297 goto test_failed_exit
;
299 if ( my_result
!= 32 ) {
300 printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE
, (int) my_result
);
301 goto test_failed_exit
;
303 if ( *my_bufp
!= 'j' || *(my_bufp
+ (MY_BUFFER_SIZE
- 1)) != 'j' ) {
304 printf( "readv failed to get correct data \n" );
305 goto test_failed_exit
;
309 my_err
= ftruncate( my_fd
, 0 );
310 if ( my_err
== -1 ) {
311 printf( "ftruncate call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
312 goto test_failed_exit
;
315 my_err
= fstat( my_fd
, &my_sb
);
316 if ( my_err
== -1 ) {
317 printf( "fstat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
318 goto test_failed_exit
;
320 if ( my_sb
.st_size
!= 0 ) {
321 printf( "ftruncate call failed - file size is wrong \n" );
322 goto test_failed_exit
;
326 lseek( my_fd
, 0, SEEK_SET
);
327 memset( my_bufp
, 'z', MY_BUFFER_SIZE
);
328 my_iovs
[0].iov_base
= my_bufp
;
329 my_iovs
[0].iov_len
= 8;
330 my_iovs
[1].iov_base
= (my_bufp
+ MY_BUFFER_SIZE
- 8) ;
331 my_iovs
[1].iov_len
= 8;
332 my_result
= writev( my_fd
, &my_iovs
[0], 2 );
333 if ( my_result
== -1 ) {
334 printf( "writev call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
335 goto test_failed_exit
;
337 if ( my_result
!= 16 ) {
338 printf( "writev failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE
, (int) my_result
);
339 goto test_failed_exit
;
342 /* now verify the writev worked OK */
343 lseek( my_fd
, 0, SEEK_SET
);
344 bzero( (void *)my_bufp
, MY_BUFFER_SIZE
);
345 my_iovs
[0].iov_base
= my_bufp
;
346 my_iovs
[0].iov_len
= 8;
347 my_iovs
[1].iov_base
= (my_bufp
+ MY_BUFFER_SIZE
- 8) ;
348 my_iovs
[1].iov_len
= 8;
350 my_result
= readv( my_fd
, &my_iovs
[0], 2 );
351 if ( my_result
== -1 ) {
352 printf( "readv call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
353 goto test_failed_exit
;
355 if ( my_result
!= 16 ) {
356 printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE
, (int) my_result
);
357 goto test_failed_exit
;
359 if ( *my_bufp
!= 'z' || *(my_bufp
+ (MY_BUFFER_SIZE
- 1)) != 'z' ) {
360 printf( "readv failed to get correct data \n" );
361 goto test_failed_exit
;
364 /* test pread and pwrite */
365 my_current_offset
= lseek( my_fd
, 0, SEEK_CUR
);
366 if ( my_current_offset
== -1 ) {
367 printf( "lseek call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
368 goto test_failed_exit
;
371 my_result
= pwrite( my_fd
, "jer", 3, my_current_offset
);
372 if ( my_result
== -1 ) {
373 printf( "pwrite call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
374 goto test_failed_exit
;
376 if ( my_result
!= 3 ) {
377 printf( "pwrite failed to write all the data \n" );
378 goto test_failed_exit
;
381 /* make sure file position did not advance */
382 if ( my_current_offset
!= lseek( my_fd
, 0, SEEK_CUR
) ) {
383 printf( "pwrite advanced file positiion \n" );
384 goto test_failed_exit
;
387 bzero( (void *)my_bufp
, MY_BUFFER_SIZE
);
388 my_result
= pread( my_fd
, my_bufp
, 3, my_current_offset
);
389 if ( my_result
== -1 ) {
390 printf( "pread call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
391 goto test_failed_exit
;
393 if ( my_result
!= 3 ) {
394 printf( "pread failed to write all the data \n" );
395 goto test_failed_exit
;
398 /* make sure file position did not advance */
399 if ( my_current_offset
!= lseek( my_fd
, 0, SEEK_CUR
) ) {
400 printf( "pread advanced file positiion \n" );
401 goto test_failed_exit
;
404 /* make sure pread and pwrite transferred correct data */
405 if ( strcmp( my_bufp
, "jer" ) != 0 ) {
406 printf( "pread or pwrite failed to read / write correct data \n" );
407 goto test_failed_exit
;
411 my_err
= truncate( my_pathp
, 0 );
412 if ( my_err
== -1 ) {
413 printf( "truncate call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
414 goto test_failed_exit
;
417 my_err
= stat( my_pathp
, &my_sb
);
418 if ( my_err
== -1 ) {
419 printf( "stat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
420 goto test_failed_exit
;
422 if ( my_sb
.st_size
!= 0 ) {
423 printf( "truncate call failed - file size is wrong \n" );
424 goto test_failed_exit
;
428 goto test_passed_exit
;
436 if ( my_pathp
!= NULL
) {
438 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
440 if ( my_bufp
!= NULL
)
441 vm_deallocate(mach_task_self(), (vm_address_t
)my_bufp
, MY_BUFFER_SIZE
);
445 /* **************************************************************************************************************
446 * Test close, fpathconf, fstat, open, pathconf system calls.
447 * **************************************************************************************************************
449 int open_close_test( void * the_argp
)
453 char * my_pathp
= NULL
;
455 long my_pconf_result
;
460 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
461 if(my_kr
!= KERN_SUCCESS
){
462 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
463 goto test_failed_exit
;
467 strcat( my_pathp
, &g_target_path
[0] );
468 strcat( my_pathp
, "/" );
470 /* create a test file */
471 my_err
= create_random_name( my_pathp
, 1 );
473 goto test_failed_exit
;
476 /* test O_WRONLY case */
477 my_fd
= open( my_pathp
, O_WRONLY
, 0 );
479 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
480 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
481 goto test_failed_exit
;
484 /* test pathconf and fpathconf */
485 my_pconf_result
= pathconf( my_pathp
, _PC_PATH_MAX
);
486 if ( my_pconf_result
== -1 ) {
487 printf( "pathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
488 goto test_failed_exit
;
490 // printf( "_PC_PATH_MAX %ld \n", my_pconf_result );
491 /* results look OK? */
492 if ( my_pconf_result
< PATH_MAX
) {
493 printf( "pathconf - _PC_PATH_MAX - looks like wrong results \n" );
494 goto test_failed_exit
;
497 my_pconf_result
= fpathconf( my_fd
, _PC_NAME_MAX
);
498 if ( my_pconf_result
== -1 ) {
499 printf( "fpathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
500 goto test_failed_exit
;
502 // printf( "_PC_NAME_MAX %ld \n", my_pconf_result );
503 /* results look OK? */
504 if ( my_pconf_result
< 6 ) {
505 printf( "fpathconf - _PC_NAME_MAX - looks like wrong results \n" );
506 goto test_failed_exit
;
509 /* write some data then try to read it */
510 my_result
= write( my_fd
, "kat", 3 );
512 if ( my_result
!= 3 ) {
513 if ( sizeof( ssize_t
) > sizeof( int ) ) {
514 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
517 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
519 goto test_failed_exit
;
522 /* Try to read - this should fail since we opened file with O_WRONLY */
523 my_result
= read( my_fd
, &my_buffer
[0], sizeof(my_buffer
) );
525 if ( my_result
!= -1 ) {
526 printf( "read call should have failed with errno 9 (EBADF) \n" );
527 goto test_failed_exit
;
529 else if ( my_err
!= EBADF
) {
530 printf( "read call should have failed with errno 9 (EBADF). actually failed with %d - \"%s\" \n", my_err
, strerror( my_err
) );
531 goto test_failed_exit
;
536 /* test O_TRUNC and O_APPEND case */
537 my_fd
= open( my_pathp
, (O_RDWR
| O_TRUNC
| O_APPEND
), 0 );
539 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
540 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
541 goto test_failed_exit
;
544 my_result
= read( my_fd
, &my_buffer
[0], sizeof(my_buffer
) );
545 if ( my_result
== -1 ) {
546 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
547 goto test_failed_exit
;
549 if ( my_result
!= 0 ) {
550 printf( "read failed - should have read 0 bytes. \n" );
551 goto test_failed_exit
;
554 my_result
= write( my_fd
, "kat", 3 );
556 if ( my_result
!= 3 ) {
557 if ( sizeof( ssize_t
) > sizeof( int ) ) {
558 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
561 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
563 goto test_failed_exit
;
566 /* add some more data to the test file - this should be appended */
567 lseek( my_fd
, 0, SEEK_SET
);
568 my_result
= write( my_fd
, "zzz", 3 );
570 if ( my_result
!= 3 ) {
571 if ( sizeof( ssize_t
) > sizeof( int ) ) {
572 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
575 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
577 goto test_failed_exit
;
580 /* now verify the writes */
581 bzero( (void *)&my_buffer
[0], sizeof(my_buffer
) );
582 lseek( my_fd
, 0, SEEK_SET
);
583 my_result
= read( my_fd
, &my_buffer
[0], sizeof(my_buffer
) );
584 if ( my_result
== -1 ) {
585 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
586 goto test_failed_exit
;
588 if ( my_buffer
[0] != 'k' || my_buffer
[5] != 'z' ) {
589 printf( "read failed to get correct data \n" );
590 goto test_failed_exit
;
594 my_err
= fstat( my_fd
, &my_sb
);
595 if ( my_err
== -1 ) {
596 printf( "fstat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
597 goto test_failed_exit
;
599 if ( my_sb
.st_size
!= 6 ) {
600 printf( "fstat call failed - st_size is wrong \n" );
601 goto test_failed_exit
;
603 if ( !S_ISREG( my_sb
.st_mode
) ) {
604 printf( "fstat call failed - st_mode does not indicate regular file \n" );
605 goto test_failed_exit
;
609 goto test_passed_exit
;
617 if ( my_pathp
!= NULL
) {
619 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
624 /* **************************************************************************************************************
625 * Test link, stat and unlink system calls.
626 * **************************************************************************************************************
628 int link_stat_unlink_test( void * the_argp
)
632 char * my_pathp
= NULL
;
633 char * my_path2p
= NULL
;
634 nlink_t my_link_count
;
639 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
640 if(my_kr
!= KERN_SUCCESS
){
641 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
642 goto test_failed_exit
;
645 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_path2p
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
646 if(my_kr
!= KERN_SUCCESS
){
647 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
648 goto test_failed_exit
;
653 strcat( my_pathp
, &g_target_path
[0] );
654 strcat( my_pathp
, "/" );
656 /* create a test file */
657 my_err
= create_random_name( my_pathp
, 1 );
659 goto test_failed_exit
;
662 /* now create a name for the link file */
663 strcat( my_path2p
, my_pathp
);
664 strcat( my_path2p
, "link" );
666 /* get the current link count */
667 my_err
= stat( my_pathp
, &my_sb
);
669 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
670 goto test_failed_exit
;
672 my_link_count
= my_sb
.st_nlink
;
674 /* check file size (should be 0) */
675 if ( my_sb
.st_size
!= 0 ) {
676 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
677 printf( "st_size is not 0 \n" );
678 goto test_failed_exit
;
681 /* change file size */
682 my_fd
= open( my_pathp
, O_RDWR
, 0 );
684 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
685 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
686 goto test_failed_exit
;
688 my_result
= write( my_fd
, "kat", 3 );
690 if ( my_result
!= 3 ) {
691 if ( sizeof( ssize_t
) > sizeof( int ) ) {
692 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
695 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
697 goto test_failed_exit
;
702 /* now link another file to our test file and recheck link count */
703 my_err
= link( my_pathp
, my_path2p
);
705 printf( "link call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
706 goto test_failed_exit
;
708 my_err
= stat( my_pathp
, &my_sb
);
710 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
711 goto test_failed_exit
;
713 if ( (my_link_count
+ 1) != my_sb
.st_nlink
) {
714 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
715 printf( "incorrect st_nlink \n" );
716 goto test_failed_exit
;
719 /* check file size (should be 3) */
720 if ( my_sb
.st_size
!= 3 ) {
721 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
722 printf( "st_size is not 3 \n" );
723 goto test_failed_exit
;
726 /* now make sure unlink works OK */
727 my_err
= unlink( my_path2p
);
729 printf( "unlink call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
730 goto test_failed_exit
;
732 my_err
= stat( my_pathp
, &my_sb
);
734 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
735 goto test_failed_exit
;
737 if ( my_link_count
!= my_sb
.st_nlink
) {
738 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
739 printf( "incorrect st_nlink \n" );
740 goto test_failed_exit
;
744 goto test_passed_exit
;
752 if ( my_pathp
!= NULL
) {
754 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
756 if ( my_path2p
!= NULL
) {
758 vm_deallocate(mach_task_self(), (vm_address_t
)my_path2p
, PATH_MAX
);
763 /* **************************************************************************************************************
764 * Test chdir and fchdir system calls.
765 * **************************************************************************************************************
767 int chdir_fchdir_test( void * the_argp
)
771 char * my_pathp
= NULL
;
772 char * my_file_namep
;
777 char *cwd
= getwd(NULL
); /* Save current working directory so we can restore later */
779 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
780 if(my_kr
!= KERN_SUCCESS
){
781 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
782 goto test_failed_exit
;
786 strcat( my_pathp
, &g_target_path
[0] );
787 strcat( my_pathp
, "/" );
789 /* create a test file */
790 my_err
= create_random_name( my_pathp
, 1 );
792 goto test_failed_exit
;
795 /* test by doing a stat on the test file using a full path and a partial path.
796 * get full path first.
798 my_err
= stat( my_pathp
, &my_sb
);
800 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
801 goto test_failed_exit
;
804 /* now do the chdir to our test directory and then do the stat relative to that location */
805 my_err
= chdir( &g_target_path
[0] );
807 printf( "chdir call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
808 goto test_failed_exit
;
811 my_file_namep
= strrchr( my_pathp
, '/' );
813 my_err
= stat( my_file_namep
, &my_sb2
);
815 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
816 goto test_failed_exit
;
819 /* both stat buffers should contain the same data since they should be referencing the same
822 if ( my_sb
.st_ino
!= my_sb2
.st_ino
|| my_sb
.st_size
!= my_sb2
.st_size
||
823 my_sb
.st_mtimespec
.tv_sec
!= my_sb2
.st_mtimespec
.tv_sec
||
824 my_sb
.st_mtimespec
.tv_nsec
!= my_sb2
.st_mtimespec
.tv_nsec
) {
825 printf( "chdir call appears to have failed. stat buffer contents do not match! \n" );
826 goto test_failed_exit
;
829 /* now change our current directory to "/" and use fchdir to get back to our test directory */
830 my_err
= chdir( "/" );
832 printf( "chdir call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
833 goto test_failed_exit
;
836 /* we should not find our test file at the root of the volume */
837 my_err
= stat( my_file_namep
, &my_sb2
);
839 printf( "chdir to root volume has failed \n" );
840 goto test_failed_exit
;
843 /* get a file descriptor to the test directory for use with fchdir */
844 my_fd
= open( &g_target_path
[0], O_RDONLY
, 0 );
846 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
847 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path
[0] );
848 goto test_failed_exit
;
851 my_err
= fchdir( my_fd
);
852 if ( my_err
== -1 ) {
853 printf( "fchdir call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
854 goto test_failed_exit
;
857 my_err
= stat( my_file_namep
, &my_sb2
);
859 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
860 goto test_failed_exit
;
863 /* both stat buffers should contain the same data since they should be referencing the same
866 if ( my_sb
.st_ino
!= my_sb2
.st_ino
|| my_sb
.st_size
!= my_sb2
.st_size
||
867 my_sb
.st_mtimespec
.tv_sec
!= my_sb2
.st_mtimespec
.tv_sec
||
868 my_sb
.st_mtimespec
.tv_nsec
!= my_sb2
.st_mtimespec
.tv_nsec
) {
869 printf( "chdir call appears to have failed. stat buffer contents do not match! \n" );
870 goto test_failed_exit
;
874 goto test_passed_exit
;
882 if ( my_pathp
!= NULL
) {
884 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
886 if ( chdir(cwd
) != 0) /* Changes back to original directory, don't screw up the env. */
891 /* **************************************************************************************************************
892 * Test access, chmod and fchmod system calls.
893 * **************************************************************************************************************
895 int access_chmod_fchmod_test( void * the_argp
)
901 char * my_pathp
= NULL
;
911 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
912 if(my_kr
!= KERN_SUCCESS
){
913 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
914 goto test_failed_exit
;
918 strcat( my_pathp
, &g_target_path
[0] );
919 strcat( my_pathp
, "/" );
921 /* create a test file */
922 my_err
= create_random_name( my_pathp
, 1 );
924 goto test_failed_exit
;
929 my_err
= chmod( my_pathp
, S_IRWXU
);
930 if ( my_err
== -1 ) {
931 printf( "chmod call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
932 goto test_failed_exit
;
935 my_err
= chmod( my_pathp
, (S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
) );
936 if ( my_err
== -1 ) {
937 printf( "chmod call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
938 goto test_failed_exit
;
941 /* test access - this should fail */
942 my_err
= access( my_pathp
, (X_OK
) );
944 printf( "access call should have failed, but did not. \n" );
945 goto test_failed_exit
;
947 else if ( my_err
== -1 ) {
951 /* special case when running as root - we get back EPERM when running as root */
953 if ( ( tmp
== 0 && my_err
!= EPERM
) || (tmp
!= 0 && my_err
!= EACCES
) ) {
954 printf( "access failed with errno %d - %s. \n", my_err
, strerror( my_err
) );
955 goto test_failed_exit
;
959 /* verify correct modes are set */
960 my_err
= stat( my_pathp
, &my_sb
);
962 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
963 goto test_failed_exit
;
966 if ( (my_sb
.st_mode
& (S_IRWXO
| S_IXGRP
)) != 0 ||
967 (my_sb
.st_mode
& (S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
)) == 0 ) {
968 printf( "chmod call appears to have failed. stat shows incorrect values in st_mode! \n" );
969 goto test_failed_exit
;
973 /* another test for the access system call -- refer ro radar# 6725311 */
977 * This test makes sure that the access system call does not give the current user extra
978 * permissions on files the current user does not own. From radar #6725311, this could
979 * happen when the current user calls access() on a file owned by the current user in
980 * the same directory as the other files not owned by the current user.
982 * Note: This test expects that the effective uid (euid) is set to root.
986 /* Create a file that root owns */
987 file_handle
= fopen(FILE_NOTME
, "w");
990 /* Currently running as root (through settid manipulation), switch to running as the current user. */
992 my_err
= syscall(SYS_settid
, ruid
, KAUTH_GID_NONE
);
994 printf("Failed to settid to non-root with error %d:%s\n", errno
, strerror(errno
));
995 goto test_failed_exit
;
998 /* Create a file that the current user owns */
999 file_handle
= fopen(FILE_ME
, "w");
1000 fclose(file_handle
);
1004 /* Try to remove the file owned by root (this should fail). */
1005 my_err
= unlink(FILE_NOTME
);
1012 printf("Unresolved: First attempt deleted '" FILE_NOTME
"'! \n");
1015 printf("Status: First attempt to delete '" FILE_NOTME
"' failed with error %d - %s.\n", my_err
, strerror( my_err
));
1017 /* Set _DELETE_OK on a file that the current user owns */
1018 access(FILE_ME
, _DELETE_OK
);
1020 /* Try to remove the file owned by root again (should give us: EPERM [13]) */
1021 my_err
= unlink(FILE_NOTME
);
1028 printf("Failed: Second attempt deleted '" FILE_NOTME
"'!\n");
1030 } else if (my_err
== 13) {
1031 printf("Passed: Second attempt to delete '" FILE_NOTME
"' failed with error %d - %s.\n", my_err
, strerror( my_err
));
1033 printf("Failed: Second attempt to delete '" FILE_NOTME
"' failed with error %d - %s.\n", my_err
, strerror( my_err
));
1038 /* Reset to running as root */
1039 my_err
= syscall(SYS_settid
, KAUTH_UID_NONE
, KAUTH_GID_NONE
);
1041 printf("Failed to revert to root using settid with error %d:%s\n", errno
, strerror(errno
));
1042 goto test_failed_exit
;
1044 if(error_occurred
== 1) {
1045 goto test_failed_exit
;
1053 my_fd
= open( my_pathp
, O_RDONLY
, 0 );
1054 if ( my_fd
== -1 ) {
1055 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1056 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path
[0] );
1057 goto test_failed_exit
;
1060 my_err
= fchmod( my_fd
, S_IRWXU
);
1061 if ( my_err
== -1 ) {
1062 printf( "fchmod call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1063 goto test_failed_exit
;
1066 my_err
= stat( my_pathp
, &my_sb
);
1067 if ( my_err
!= 0 ) {
1068 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1069 goto test_failed_exit
;
1072 /* verify correct modes are set */
1073 if ( (my_sb
.st_mode
& (S_IRWXG
| S_IRWXO
)) != 0 ||
1074 (my_sb
.st_mode
& (S_IRWXU
)) == 0 ) {
1075 printf( "fchmod call appears to have failed. stat shows incorrect values in st_mode! \n" );
1076 goto test_failed_exit
;
1080 goto test_passed_exit
;
1088 if ( my_pathp
!= NULL
) {
1090 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
1095 static bool _prime_groups(void)
1098 * prime groups with a known list to ensure consistent test behavior
1101 gid_t my_exp_groups
[] = { getegid(), 20, 61, 12 };
1104 my_err
= setgroups( ( sizeof(my_exp_groups
) / sizeof(*my_exp_groups
) ), &my_exp_groups
[0] );
1105 if ( my_err
== -1 ) {
1106 printf( "initial setgroups call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1113 /* **************************************************************************************************************
1114 * Test chown, fchown, lchown, lstat, readlink, symlink system calls.
1115 * **************************************************************************************************************
1117 int chown_fchown_lchown_lstat_symlink_test( void * the_argp
)
1119 int my_err
, my_group_count
, i
;
1121 char * my_pathp
= NULL
;
1122 char * my_link_pathp
= NULL
;
1124 gid_t my_orig_gid
, my_new_gid1
= 0, my_new_gid2
= 0;
1127 gid_t my_groups
[ NGROUPS_MAX
];
1128 char my_buffer
[ 64 ];
1129 kern_return_t my_kr
;
1131 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
1132 if(my_kr
!= KERN_SUCCESS
){
1133 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1134 goto test_failed_exit
;
1138 strcat( my_pathp
, &g_target_path
[0] );
1139 strcat( my_pathp
, "/" );
1141 /* create a test file */
1142 my_err
= create_random_name( my_pathp
, 1 );
1143 if ( my_err
!= 0 ) {
1144 goto test_failed_exit
;
1147 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_link_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
1148 if(my_kr
!= KERN_SUCCESS
){
1149 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1150 goto test_failed_exit
;
1153 *my_link_pathp
= 0x00;
1154 strcat( my_link_pathp
, &g_target_path
[0] );
1155 strcat( my_link_pathp
, "/" );
1157 /* get a test file name for the link */
1158 my_err
= create_random_name( my_link_pathp
, 0 );
1159 if ( my_err
!= 0 ) {
1160 goto test_failed_exit
;
1163 if ( !_prime_groups() ) {
1164 goto test_failed_exit
;
1167 /* set up by getting a list of groups */
1168 my_group_count
= getgroups( NGROUPS_MAX
, &my_groups
[0] );
1170 if ( my_group_count
== -1 || my_group_count
< 1 ) {
1171 printf( "getgroups call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1172 goto test_failed_exit
;
1175 my_err
= stat( my_pathp
, &my_sb
);
1176 if ( my_err
!= 0 ) {
1177 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1178 goto test_failed_exit
;
1181 /* now change group owner to something other than current value */
1182 my_orig_gid
= my_sb
.st_gid
;
1183 my_orig_uid
= my_sb
.st_uid
;
1185 for ( i
= 0; i
< my_group_count
; i
++ ) {
1186 if ( my_orig_gid
!= my_groups
[ i
] ) {
1187 if ( my_new_gid1
== 0 ) {
1188 my_new_gid1
= my_groups
[ i
];
1190 else if( my_new_gid1
!= my_groups
[ i
] ) {
1191 my_new_gid2
= my_groups
[ i
];
1196 if ( i
>= my_group_count
) {
1197 printf( "not enough groups to choose from. st_gid is the same as current groups! \n" );
1198 goto test_failed_exit
;
1201 my_err
= chown( my_pathp
, my_orig_uid
, my_new_gid1
);
1202 if ( my_err
!= 0 ) {
1203 printf( "chown call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1204 goto test_failed_exit
;
1207 /* make sure the group owner was changed */
1208 my_err
= stat( my_pathp
, &my_sb
);
1209 if ( my_err
!= 0 ) {
1210 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1211 goto test_failed_exit
;
1213 if ( my_sb
.st_gid
== my_orig_gid
) {
1214 printf( "chown call failed. st_gid is not correct! \n" );
1215 goto test_failed_exit
;
1218 /* change group owner back using fchown */
1219 my_fd
= open( my_pathp
, O_RDWR
, 0 );
1220 if ( my_fd
== -1 ) {
1221 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1222 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path
[0] );
1223 goto test_failed_exit
;
1226 my_err
= fchown( my_fd
, my_orig_uid
, my_new_gid2
);
1227 if ( my_err
!= 0 ) {
1228 printf( "fchown call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1229 goto test_failed_exit
;
1232 /* make sure the group owner was changed back to the original value */
1233 my_err
= stat( my_pathp
, &my_sb
);
1234 if ( my_err
!= 0 ) {
1235 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1236 goto test_failed_exit
;
1238 if ( my_sb
.st_gid
== my_new_gid1
) {
1239 printf( "fchown call failed. st_gid is not correct! \n" );
1240 goto test_failed_exit
;
1243 /* create a link file and test lchown */
1244 my_err
= symlink( my_pathp
, my_link_pathp
);
1245 if ( my_err
!= 0 ) {
1246 printf( "symlink call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1247 goto test_failed_exit
;
1250 my_err
= lstat( my_link_pathp
, &my_sb
);
1251 if ( my_err
!= 0 ) {
1252 printf( "lstat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1253 goto test_failed_exit
;
1256 /* now change group owner to something other than current value */
1257 my_orig_gid
= my_sb
.st_gid
;
1258 my_orig_uid
= my_sb
.st_uid
;
1259 my_err
= lchown( my_link_pathp
, my_orig_uid
, my_new_gid1
);
1260 if ( my_err
!= 0 ) {
1261 printf( "lchown call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1262 goto test_failed_exit
;
1265 /* make sure the group owner was changed to new value */
1266 my_err
= lstat( my_link_pathp
, &my_sb
);
1267 if ( my_err
!= 0 ) {
1268 printf( "lstat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1269 goto test_failed_exit
;
1271 if ( my_sb
.st_gid
== my_new_gid2
) {
1272 printf( "lchown call failed. st_gid is not correct! \n" );
1273 goto test_failed_exit
;
1276 /* make sure we can read the symlink file */
1277 my_result
= readlink( my_link_pathp
, &my_buffer
[0], sizeof(my_buffer
) );
1278 if ( my_result
== -1 ) {
1279 printf( "readlink call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1280 goto test_failed_exit
;
1282 /* make sure we read some data */
1283 if ( my_result
< 1 ) {
1284 printf( "readlink failed to read any data. \n" );
1285 goto test_failed_exit
;
1289 goto test_passed_exit
;
1297 if ( my_pathp
!= NULL
) {
1299 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
1301 if ( my_link_pathp
!= NULL
) {
1302 unlink( my_link_pathp
);
1303 vm_deallocate(mach_task_self(), (vm_address_t
)my_link_pathp
, PATH_MAX
);
1308 /* **************************************************************************************************************
1309 * Test fstatfs, getattrlist, getfsstat, statfs, getfsstat64, statfs64, fstatfs64 system calls.
1310 * **************************************************************************************************************
1314 struct vol_attr_buf
{
1317 u_int32_t io_blksize
;
1320 typedef struct vol_attr_buf vol_attr_buf
;
1322 #define STATFS_TEST_PATH "/tmp"
1324 int fs_stat_tests( void * the_argp
)
1326 int my_err
, my_count
, i
;
1327 int my_buffer_size
, my_buffer64_size
;
1332 struct attrlist my_attrlist
;
1333 vol_attr_buf my_attr_buf
;
1334 void * my_bufferp
= NULL
;
1335 struct statfs
* my_statfsp
;
1336 kern_return_t my_kr
;
1338 void * my_buffer64p
= NULL
;
1339 struct statfs64
* my_statfs64p
;
1341 my_buffer64_size
= (sizeof(struct statfs64
) * 10);
1343 my_kr
= vm_allocate((vm_map_t
) mach_task_self(),(vm_address_t
*) &my_buffer64p
, my_buffer64_size
, VM_FLAGS_ANYWHERE
);
1344 if(my_kr
!= KERN_SUCCESS
){
1345 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1346 goto test_failed_exit
;
1349 my_buffer_size
= (sizeof(struct statfs
) * 10);
1351 my_kr
= vm_allocate((vm_map_t
) mach_task_self(),(vm_address_t
*) &my_bufferp
, my_buffer_size
, VM_FLAGS_ANYWHERE
);
1352 if(my_kr
!= KERN_SUCCESS
){
1353 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1354 goto test_failed_exit
;
1357 my_statfsp
= (struct statfs
*) my_bufferp
;
1358 my_err
= statfs( STATFS_TEST_PATH
, my_statfsp
);
1359 if ( my_err
== -1 ) {
1360 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1361 goto test_failed_exit
;
1363 if ( memcmp( &my_statfsp
->f_fstypename
[0], "ufs", 3 ) == 0 ) {
1367 my_count
= getfsstat( (struct statfs
*)my_bufferp
, my_buffer_size
, MNT_NOWAIT
);
1368 if ( my_count
== -1 ) {
1369 printf( "getfsstat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1370 goto test_failed_exit
;
1373 /* validate results */
1374 my_statfsp
= (struct statfs
*) my_bufferp
;
1375 for ( i
= 0; i
< my_count
; i
++, my_statfsp
++ ) {
1376 if ( memcmp( &my_statfsp
->f_fstypename
[0], "hfs", 3 ) == 0 ||
1377 memcmp( &my_statfsp
->f_fstypename
[0], "ufs", 3 ) == 0 ||
1378 memcmp( &my_statfsp
->f_fstypename
[0], "devfs", 5 ) == 0 ||
1379 memcmp( &my_statfsp
->f_fstypename
[0], "volfs", 5 ) == 0 ) {
1380 /* found a valid entry */
1384 if ( i
>= my_count
) {
1385 printf( "getfsstat call failed. could not find valid f_fstypename! \n" );
1386 goto test_failed_exit
;
1389 /* now try statfs64 */
1390 my_statfs64p
= (struct statfs64
*) my_buffer64p
;
1391 my_err
= statfs64( STATFS_TEST_PATH
, my_statfs64p
);
1392 if ( my_err
== -1 ) {
1393 printf( "statfs64 call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1394 goto test_failed_exit
;
1396 if ( my_statfs64p
->f_fsid
.val
[0] != my_statfsp
->f_fsid
.val
[0] ||
1397 my_statfs64p
->f_fsid
.val
[1] != my_statfsp
->f_fsid
.val
[1] ) {
1398 printf( "statfs64 call failed. wrong f_fsid! \n" );
1399 goto test_failed_exit
;
1402 my_count
= getfsstat64( (struct statfs64
*)my_buffer64p
, my_buffer64_size
, MNT_NOWAIT
);
1403 if ( my_count
== -1 ) {
1404 printf( "getfsstat64 call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1405 goto test_failed_exit
;
1408 /* validate results */
1409 my_statfs64p
= (struct statfs64
*) my_buffer64p
;
1410 for ( i
= 0; i
< my_count
; i
++, my_statfs64p
++ ) {
1411 if ( memcmp( &my_statfs64p
->f_fstypename
[0], "hfs", 3 ) == 0 ||
1412 memcmp( &my_statfs64p
->f_fstypename
[0], "ufs", 3 ) == 0 ||
1413 memcmp( &my_statfs64p
->f_fstypename
[0], "devfs", 5 ) == 0 ||
1414 memcmp( &my_statfs64p
->f_fstypename
[0], "volfs", 5 ) == 0 ) {
1415 /* found a valid entry */
1419 if ( i
>= my_count
) {
1420 printf( "getfsstat64 call failed. could not find valid f_fstypename! \n" );
1421 goto test_failed_exit
;
1424 /* set up to validate results via multiple sources. we use getattrlist to get volume
1425 * related attributes to verify against results from fstatfs and statfs - but only if
1426 * we are not targeting ufs volume since it doesn't support getattr calls
1428 if ( is_ufs
== 0 ) {
1429 memset( &my_attrlist
, 0, sizeof(my_attrlist
) );
1430 my_attrlist
.bitmapcount
= ATTR_BIT_MAP_COUNT
;
1431 my_attrlist
.volattr
= (ATTR_VOL_SIZE
| ATTR_VOL_IOBLOCKSIZE
);
1432 my_err
= getattrlist( "/", &my_attrlist
, &my_attr_buf
, sizeof(my_attr_buf
), 0 );
1433 if ( my_err
!= 0 ) {
1434 printf( "getattrlist call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1435 goto test_failed_exit
;
1439 /* open to use as test file for fstatfs */
1440 my_fd
= open( STATFS_TEST_PATH
, O_RDONLY
, 0 );
1441 if ( my_fd
== -1 ) {
1442 printf( "open call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1443 goto test_failed_exit
;
1446 /* testing fstatfs64 */
1447 my_statfs64p
= (struct statfs64
*) my_buffer64p
;
1448 my_err
= fstatfs64( my_fd
, my_statfs64p
);
1449 if ( my_err
== -1 ) {
1450 printf( "fstatfs64 call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1451 goto test_failed_exit
;
1454 /* validate results - assumes we only boot from hfs or ufs */
1455 if ( !(memcmp( &my_statfs64p
->f_fstypename
[0], "hfs", 3 ) == 0 ||
1456 memcmp( &my_statfs64p
->f_fstypename
[0], "ufs", 3 ) == 0) ) {
1457 printf( "fstatfs64 call failed. could not find valid f_fstypename! \n" );
1458 goto test_failed_exit
;
1461 /* testing fstatfs */
1462 my_statfsp
= (struct statfs
*) my_bufferp
;
1463 my_err
= fstatfs( my_fd
, my_statfsp
);
1464 if ( my_err
== -1 ) {
1465 printf( "fstatfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1466 goto test_failed_exit
;
1469 /* validate results */
1470 if ( !(memcmp( &my_statfsp
->f_fstypename
[0], "hfs", 3 ) == 0 ||
1471 memcmp( &my_statfsp
->f_fstypename
[0], "ufs", 3 ) == 0) ) {
1472 printf( "fstatfs call failed. could not find valid f_fstypename! \n" );
1473 goto test_failed_exit
;
1475 my_io_size
= my_statfsp
->f_iosize
;
1476 my_fsid
= my_statfsp
->f_fsid
;
1477 if ( is_ufs
== 0 && my_statfsp
->f_iosize
!= my_attr_buf
.io_blksize
) {
1478 printf( "fstatfs and getattrlist results do not match for volume block size \n" );
1479 goto test_failed_exit
;
1482 /* try again with statfs */
1483 my_err
= statfs( STATFS_TEST_PATH
, my_statfsp
);
1484 if ( my_err
== -1 ) {
1485 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1486 goto test_failed_exit
;
1489 /* validate results */
1490 if ( my_io_size
!= my_statfsp
->f_iosize
|| my_fsid
.val
[0] != my_statfsp
->f_fsid
.val
[0] ||
1491 my_fsid
.val
[1] != my_statfsp
->f_fsid
.val
[1] ) {
1492 printf( "statfs call failed. wrong f_iosize or f_fsid! \n" );
1493 goto test_failed_exit
;
1495 if ( is_ufs
== 0 && my_statfsp
->f_iosize
!= my_attr_buf
.io_blksize
) {
1496 printf( "statfs and getattrlist results do not match for volume block size \n" );
1497 goto test_failed_exit
;
1501 goto test_passed_exit
;
1509 if ( my_bufferp
!= NULL
) {
1510 vm_deallocate(mach_task_self(), (vm_address_t
)my_bufferp
, my_buffer_size
);
1512 if ( my_buffer64p
!= NULL
) {
1513 vm_deallocate(mach_task_self(), (vm_address_t
)my_buffer64p
, my_buffer64_size
);
1519 /* **************************************************************************************************************
1520 * Test getpid, getppid, and pipe system calls.
1521 * **************************************************************************************************************
1523 int getpid_getppid_pipe_test( void * the_argp
)
1525 int my_err
, my_status
;
1526 pid_t my_pid
, my_wait_pid
;
1528 int my_fildes
[2] = {-1, -1};
1529 off_t my_current_offset
;
1530 char my_pid_string
[64];
1532 my_err
= pipe( &my_fildes
[0] );
1533 if ( my_err
!= 0 ) {
1534 printf( "pipe call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1535 goto test_failed_exit
;
1538 /* make sure we can't seek on a pipe */
1539 my_current_offset
= lseek( my_fildes
[0], 0, SEEK_CUR
);
1540 if ( my_current_offset
!= -1 ) {
1541 printf( "lseek on pipe should fail but did not \n" );
1542 goto test_failed_exit
;
1545 /* fork here and use pipe to communicate */
1547 if ( my_pid
== -1 ) {
1548 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
1549 goto test_failed_exit
;
1551 else if ( my_pid
== 0 ) {
1553 unsigned long my_ppid
;
1556 close( my_fildes
[1] ); /* close write end of pipe */
1559 /* get the parent's pid using getppid and from the parent (using getpid in porent) */
1560 my_count
= read( my_fildes
[0], &my_buffer
[0], sizeof(my_buffer
) );
1561 if ( my_count
== -1 ) {
1562 printf( "read from pipe failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1566 /* parent wrote (to our pipe) its pid as character string */
1567 my_ppid
= strtoul( &my_buffer
[0], NULL
, 10 );
1568 if ( my_ppid
== 0 ) {
1569 printf( "strtoul failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1573 if ( getppid( ) != my_ppid
) {
1574 printf( "getppid failed. pid we got from parent does not match getppid result. \n" );
1580 /* parent process - get our pid using getpid and send it to child for verification */
1581 close( my_fildes
[0] ); /* close read end of pipe */
1584 sprintf( &my_pid_string
[0], "%d\n", getpid( ) );
1586 my_count
= write( my_fildes
[1], &my_pid_string
[0], sizeof(my_pid_string
) );
1587 if ( my_count
== -1 ) {
1588 printf( "write to pipe failed. got errno %d - %s. \n", errno
, strerror( errno
) );
1589 goto test_failed_exit
;
1592 /* wait for child to exit */
1593 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
1594 if ( my_wait_pid
== -1 ) {
1595 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
1596 goto test_failed_exit
;
1599 /* wait4 should return our child's pid when it exits */
1600 if ( my_wait_pid
!= my_pid
) {
1601 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid
, my_pid
);
1602 goto test_failed_exit
;
1605 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) {
1606 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status
);
1607 goto test_failed_exit
;
1611 goto test_passed_exit
;
1617 if ( my_fildes
[0] != -1 )
1618 close( my_fildes
[0] );
1619 if ( my_fildes
[1] != -1 )
1620 close( my_fildes
[1] );
1625 /* **************************************************************************************************************
1626 * Test getauid, gettid, getuid, geteuid, issetugid, setaudit_addr, seteuid, settid, settid_with_pid, setuid system calls.
1627 * **************************************************************************************************************
1629 int uid_tests( void * the_argp
)
1631 int my_err
, my_status
;
1632 pid_t my_pid
, my_wait_pid
;
1634 if ( g_skip_setuid_tests
!= 0 ) {
1635 printf("\t skipping this test \n");
1637 goto test_passed_exit
;
1640 /* test issetugid - should return 1 when not root and 0 when root
1641 * Figuring out setugid will not work in single-user mode; skip
1642 * this test in that case.
1644 if (!g_is_single_user
) {
1645 my_err
= issetugid( );
1646 if ( getuid( ) == 0 ) {
1647 if ( my_err
== 1 ) {
1648 printf( "issetugid should return false \n" );
1649 goto test_failed_exit
;
1653 if ( my_err
== 0 ) {
1654 printf( "issetugid should return true \n" );
1655 goto test_failed_exit
;
1661 * fork here and do the setuid work in the child
1664 if ( my_pid
== -1 ) {
1665 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
1666 goto test_failed_exit
;
1668 else if ( my_pid
== 0 ) {
1672 uid_t my_ruid
, my_euid
;
1673 uid_t my_uid
, my_temp_uid
;
1674 gid_t my_gid
, my_temp_gid
;
1675 auditinfo_addr_t my_aia
;
1677 my_ruid
= getuid( );
1678 my_euid
= geteuid( );
1679 if ( my_ruid
== my_euid
) {
1683 /* Test getauid, gettid, setaudit_addr, settid, settid_with_pid */
1684 /* get our current uid and gid for comparison later */
1688 my_err
= syscall( SYS_settid
, 4444, 5555 );
1689 //my_err = settid( 4444, 5555 );
1691 printf( "settid call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1695 my_err
= syscall( SYS_gettid
, &my_temp_uid
, &my_temp_gid
);
1696 //my_err = gettid( &my_temp_uid, &my_temp_gid );
1698 printf( "gettid call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1701 if (my_temp_uid
!= 4444) {
1702 printf("get / settid test failed - wrong uid was set - %d \n", my_temp_uid
);
1705 if (my_temp_gid
!= 5555) {
1706 printf("get / settid test failed - wrong gid was set - %d \n", my_temp_gid
);
1710 /* resume original identity */
1711 my_err
= syscall( SYS_settid
, KAUTH_UID_NONE
, KAUTH_GID_NONE
);
1712 //my_err = settid( KAUTH_UID_NONE, KAUTH_GID_NONE );
1714 printf( "settid revert - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1718 /* values should be returned to original settings */
1719 my_temp_uid
= getuid( );
1720 if (my_temp_uid
== 4444) {
1721 printf("test failed - wrong uid was set - %d \n", my_temp_uid
);
1724 my_temp_gid
= getgid( );
1725 if (my_temp_gid
== 5555) {
1726 printf("test failed - wrong gid was set - %d \n", my_temp_gid
);
1731 * Assume the identity of our parent.
1733 my_err
= syscall( SYS_settid_with_pid
, getppid( ), 1 );
1734 //my_err = settid_with_pid, my_target_pid, 1 );
1736 printf( "settid_with_pid assume - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1741 * Resume our identity.
1743 my_err
= syscall( SYS_settid_with_pid
, 0, 0 );
1744 //my_err = settid_with_pid( my_target_pid, 0 );
1746 printf( "settid_with_pid resume - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1751 * test to make sure setaudit_addr doesn't cause audit info to get lost from
1754 bzero( &my_aia
, sizeof(my_aia
) );
1755 my_aia
.ai_auid
= 442344;
1756 my_aia
.ai_asid
= AU_ASSIGN_ASID
;
1757 my_aia
.ai_termid
.at_type
= AU_IPv4
;
1758 my_err
= setaudit_addr( &my_aia
, sizeof(my_aia
) );
1760 printf( "setaudit_addr - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1765 my_err
= getaudit_addr( &my_aia
, sizeof(my_aia
) );
1767 printf( "getaudit_addr - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1770 //printf("new audit ID is %d \n", my_aia.ai_auid);
1772 if (my_aia
.ai_auid
!= 442344) {
1773 printf("test failed - wrong audit ID was set - %d \n", my_aia
.ai_auid
);
1777 /* change real uid and effective uid to current euid */
1778 my_err
= setuid( my_euid
);
1779 if ( my_err
== -1 ) {
1780 printf( "setuid call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1783 if ( getuid( ) != my_euid
) {
1784 printf( "setuid call failed to set the real uid \n" );
1788 /* change effective uid to current euid - really a NOP */
1789 my_err
= seteuid( my_euid
);
1790 if ( my_err
== -1 ) {
1791 printf( "seteuid call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1794 if ( geteuid( ) != my_euid
) {
1795 printf( "seteuid call failed to set the original euid \n" );
1799 /* change real uid and effective uid to original real uid */
1800 my_err
= setuid( my_ruid
);
1801 if ( my_err
== -1 ) {
1802 printf( "setuid call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1805 if ( getuid( ) != my_ruid
) {
1806 printf( "setuid call failed to set the real uid \n" );
1815 * wait for child to exit
1817 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
1818 if ( my_wait_pid
== -1 ) {
1819 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
1820 goto test_failed_exit
;
1823 /* wait4 should return our child's pid when it exits */
1824 if ( my_wait_pid
!= my_pid
) {
1825 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid
, my_pid
);
1826 goto test_failed_exit
;
1829 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) {
1830 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status
);
1831 goto test_failed_exit
;
1835 goto test_passed_exit
;
1844 /* **************************************************************************************************************
1845 * Test mknod, sync system calls.
1846 * **************************************************************************************************************
1848 int mknod_sync_test( void * the_argp
)
1851 char * my_pathp
= NULL
;
1852 kern_return_t my_kr
;
1854 if ( g_skip_setuid_tests
!= 0 ) {
1855 printf("\t skipping this test \n");
1857 goto test_passed_exit
;
1860 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
1861 if(my_kr
!= KERN_SUCCESS
){
1862 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1863 goto test_failed_exit
;
1867 strcat( my_pathp
, "/dev/" );
1869 /* get a unique name for our test file */
1870 my_err
= create_random_name( my_pathp
, 0 );
1871 if ( my_err
!= 0 ) {
1872 goto test_failed_exit
;
1875 my_err
= mknod( my_pathp
, (S_IFCHR
| S_IRWXU
), 0 );
1876 if ( my_err
== -1 ) {
1877 printf( "mknod failed with errno %d - %s \n", errno
, strerror( errno
) );
1878 printf( "path \"%s\" \n", my_pathp
);
1879 goto test_failed_exit
;
1882 /* not really sure what to do with sync call test */
1885 goto test_passed_exit
;
1891 if ( my_pathp
!= NULL
) {
1893 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
1898 /* **************************************************************************************************************
1899 * Test chflags, fchflags system calls.
1900 * **************************************************************************************************************
1902 int chflags_fchflags_test( void * the_argp
)
1907 char * my_pathp
= NULL
;
1909 kern_return_t my_kr
;
1911 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
1912 if(my_kr
!= KERN_SUCCESS
){
1913 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1914 goto test_failed_exit
;
1918 strcat( my_pathp
, &g_target_path
[0] );
1919 strcat( my_pathp
, "/" );
1921 /* create a test file */
1922 my_err
= create_random_name( my_pathp
, 1 );
1923 if ( my_err
!= 0 ) {
1924 goto test_failed_exit
;
1927 /* make test file unchangable */
1928 my_err
= stat( my_pathp
, &my_sb
);
1929 if ( my_err
!= 0 ) {
1930 printf( "stat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1931 goto test_failed_exit
;
1934 my_flags
= (my_sb
.st_flags
| UF_IMMUTABLE
);
1935 my_err
= chflags( my_pathp
, my_flags
);
1936 if ( my_err
!= 0 ) {
1937 printf( "chflags call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1938 goto test_failed_exit
;
1941 /* should fail with EPERM since we cannot change the file now */
1942 my_fd
= open( my_pathp
, O_RDWR
, 0 );
1943 if ( my_fd
== -1 && errno
!= EPERM
) {
1944 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1945 printf( "open failed with wrong error - should be EPERM \n" );
1946 goto test_failed_exit
;
1949 /* this open should work OK */
1950 my_fd
= open( my_pathp
, O_RDONLY
, 0 );
1951 if ( my_fd
== -1 ) {
1952 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1953 goto test_failed_exit
;
1956 my_err
= stat( my_pathp
, &my_sb
);
1957 if ( my_err
!= 0 ) {
1958 printf( "stat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1959 goto test_failed_exit
;
1962 my_flags
= (my_sb
.st_flags
& ~UF_IMMUTABLE
);
1963 my_err
= fchflags( my_fd
, my_flags
);
1964 if ( my_err
!= 0 ) {
1965 printf( "chflags call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1966 goto test_failed_exit
;
1972 /* should now work */
1973 my_fd
= open( my_pathp
, O_RDWR
, 0 );
1974 if ( my_fd
== -1 ) {
1975 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
1976 goto test_failed_exit
;
1980 goto test_passed_exit
;
1988 if ( my_pathp
!= NULL
) {
1990 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
1996 /* **************************************************************************************************************
1997 * Test kill, vfork, execve system calls.
1998 * **************************************************************************************************************
2000 /* There are many new exec() situations to test now that 64-bit is in. These extra tests are in response to
2001 * rdar://4606399 and rdar://4607285. It should cover every permutation of the following variables.
2003 * - Current Process "Bitness": 64 or 32
2004 * - exec()'ed process "bitness": 64 or 32
2005 * (if 64 bit, size of page zero:) (4GB or 4KB)
2006 * - Parent Process "Bitness": 64 or 32
2008 * Test to make sure certain inheritance properties of fork()'ed children
2009 * are correctly set.
2010 * 1. 64 bit process forking() 64-bit child, child execing() 64-bit file (4GB pagezero)
2011 * 2. 64 bit process forking() 64-bit child, child execing() 64-bit file (4KB pagezero)
2012 * 3. 64 bit process forking() 64-bit child, child execing() 32-bit file
2013 * 4. 32 bit process forking() 32-bit child, child execing() 32-bit file
2014 * 5. 32 bit process forking() 32-bit child, child execing() 64 bit file (4GB pagezero)
2015 * 6. 32 bit process forking() 32-bit child, child execing() 64 bit file (4KB pagezero)
2020 int execve_kill_vfork_test( void * the_argp
)
2022 int my_err
, my_status
;
2023 pid_t my_pid
, my_wait_pid
;
2024 char * errmsg
= NULL
;
2025 char * argvs
[2] = {"", NULL
};
2026 int bits
= get_bits(); /* Gets actual processor bit-ness. */
2028 if (bits
!= 32 && bits
!= 64) {
2029 printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits());
2033 if (get_architecture() == -1) {
2034 errmsg
= "get_architecture() could not determine the CPU architecture.\n";
2035 goto test_failed_exit
;
2038 if (get_architecture() == INTEL
) {
2041 if (bits
== 64 && sizeof(long) == 8) {
2043 * Running on x86_64 hardware and running in 64-bit mode.
2044 * Check cases 1, 2, 3 and fork a child to check 4, 5, 6.
2046 errmsg
= "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4G pagezero.\n";
2047 argvs
[0] = "sleep-x86_64-4G";
2048 if (do_execve_test("helpers/sleep-x86_64-4G", argvs
, NULL
, 1)) goto test_failed_exit
;
2050 errmsg
= "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4K Pagezero.\n";
2051 argvs
[0] = "sleep-x86_64-4K";
2052 if (do_execve_test("helpers/sleep-x86_64-4K", argvs
, NULL
, 1)) goto test_failed_exit
;
2054 errmsg
= "execve failed: from x64_64 forking and exec()ing 32-bit i386 process.\n";
2055 argvs
[0] = "sleep-i386";
2056 if (do_execve_test("helpers/sleep-i386", argvs
, NULL
, 1)) goto test_failed_exit
;
2058 /* Fork off a helper process and load a 32-bit program in it to test 32->64 bit exec(). */
2059 errmsg
= "execve failed to exec the helper process.\n";
2060 argvs
[0] = "launch-i386";
2061 if (do_execve_test("helpers/launch-i386", argvs
, NULL
, 1) != 0) goto test_failed_exit
;
2063 /* Test posix_spawn for i386, x86_64 (should succeed) */
2065 if (do_spawn_test(CPU_TYPE_I386
, 0))
2066 goto test_failed_exit
;
2067 if (do_spawn_test(CPU_TYPE_X86_64
, 0))
2068 goto test_failed_exit
;
2070 else if (bits
== 64 && sizeof(long) == 4) {
2072 * Running on x86_64 hardware, but actually running in 32-bit mode.
2073 * Check cases 4, 5, 6 and fork a child to check 1, 2, 3.
2075 errmsg
= "execve failed: from i386 forking and exec()ing i386 process.\n";
2076 argvs
[0] = "sleep-i386";
2077 if (do_execve_test("helpers/sleep-i386", argvs
, NULL
, 0)) goto test_failed_exit
;
2079 errmsg
= "execve failed: from i386 forking and exec()ing x86_64 process w/ 4G pagezero.\n";
2080 argvs
[0] = "sleep-x86_64-4G";
2081 if (do_execve_test("helpers/sleep-x86_64-4G", argvs
, NULL
, 0)) goto test_failed_exit
;
2083 errmsg
= "execve failed: from i386 forking and exec()ing x86_64 process w/ 4K pagezero.\n";
2084 argvs
[0] = "sleep-x86_64-4K";
2085 if (do_execve_test("helpers/sleep-x86_64-4K", argvs
, NULL
, 0)) goto test_failed_exit
;
2087 /* Fork off a helper process and load a 64-bit program in it to test 64->32 bit exec(). */
2088 errmsg
= "execve failed to exec the helper process.\n";
2089 argvs
[0] = "launch-x86_64";
2090 if (do_execve_test("helpers/launch-x86_64", argvs
, NULL
, 1) != 0) goto test_failed_exit
;
2092 /* Test posix_spawn for i386, x86_64 (should succeed) */
2094 if (do_spawn_test(CPU_TYPE_I386
, 0))
2095 goto test_failed_exit
;
2096 if (do_spawn_test(CPU_TYPE_X86_64
, 0))
2097 goto test_failed_exit
;
2099 else if (bits
== 32) {
2100 /* Running on i386 hardware. Check cases 4. */
2101 errmsg
= "execve failed: from i386 forking and exec()ing 32-bit i386 process.\n";
2102 argvs
[0] = "sleep-i386";
2103 if (do_execve_test("helpers/sleep-i386", argvs
, NULL
, 1)) goto test_failed_exit
;
2105 /* Test posix_spawn for x86_64 (should fail), i386 (should succeed) */
2107 if (do_spawn_test(CPU_TYPE_X86_64
, 1))
2108 goto test_failed_exit
;
2109 if (do_spawn_test(CPU_TYPE_I386
, 0))
2110 goto test_failed_exit
;
2112 } else if(get_architecture() == ARM
) {
2114 #ifdef CPU_TYPE_ARM64
2116 /* Running on arm64 hardware. */
2117 errmsg
= "execve failed: from arm64 forking and exec()ing 64-bit arm process.\n";
2118 argvs
[0] = "sleep-arm";
2119 if (do_execve_test("helpers/sleep-arm64", argvs
, NULL
, 1))
2120 goto test_failed_exit
;
2122 /* Test posix_spawn for arm64 (should succeed) */
2124 if (do_spawn_test(CPU_TYPE_ARM64
, 0))
2125 goto test_failed_exit
;
2129 /* Exec arm test on both arm and arm64 */
2130 errmsg
= "execve failed: from arm forking and exec()ing 32-bit arm process.\n";
2131 argvs
[0] = "sleep-arm";
2132 if (do_execve_test("helpers/sleep-arm", argvs
, NULL
, 1))
2133 goto test_failed_exit
;
2135 /* Test posix_spawn for arm (should succeed) */
2137 if (do_spawn_test(CPU_TYPE_ARM
, 0))
2138 goto test_failed_exit
;
2142 /* Just in case someone decides we need more architectures in the future */
2143 printf("get_architecture() returned unknown architecture");
2151 printf("%s", errmsg
);
2156 /* **************************************************************************************************************
2157 * Test getegid, getgid, getgroups, setegid, setgid, setgroups system calls.
2158 * **************************************************************************************************************
2160 int groups_test( void * the_argp
)
2163 int my_group_count
, my_orig_group_count
;
2165 gid_t my_effective_gid
;
2166 gid_t my_removed_gid
;
2168 gid_t my_groups
[ NGROUPS_MAX
];
2170 if ( g_skip_setuid_tests
!= 0 ) {
2171 printf("\t skipping this test \n");
2173 goto test_passed_exit
;
2176 my_real_gid
= getgid( );
2177 my_effective_gid
= getegid( );
2179 if ( !_prime_groups() ) {
2180 goto test_failed_exit
;
2183 /* start by getting list of groups the current user belongs to */
2184 my_orig_group_count
= getgroups( NGROUPS_MAX
, &my_groups
[0] );
2186 if ( my_orig_group_count
== -1 || my_orig_group_count
< 1 ) {
2187 printf( "getgroups call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2188 goto test_failed_exit
;
2191 /* make sure real and effective gids are correct */
2192 for ( i
= 0; i
< my_orig_group_count
; i
++ ) {
2193 if ( my_groups
[i
] == my_real_gid
)
2196 if ( i
>= my_orig_group_count
) {
2197 printf( "getgid or getgroups call failed. could not find real gid in list of groups. \n" );
2198 goto test_failed_exit
;
2200 for ( i
= 0; i
< my_orig_group_count
; i
++ ) {
2201 if ( my_groups
[i
] == my_effective_gid
)
2204 if ( i
>= my_orig_group_count
) {
2205 printf( "getegid or getgroups call failed. could not find effective gid in list of groups. \n" );
2206 goto test_failed_exit
;
2209 /* remove the last group */
2210 my_removed_gid
= my_groups
[ (my_orig_group_count
- 1) ];
2211 my_err
= setgroups( (my_orig_group_count
- 1), &my_groups
[0] );
2212 if ( my_err
== -1 ) {
2213 printf( "setgroups call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2214 goto test_failed_exit
;
2217 my_group_count
= getgroups( NGROUPS_MAX
, &my_groups
[0] );
2219 if ( my_group_count
== -1 || my_group_count
< 1 ) {
2220 printf( "getgroups call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2221 goto test_failed_exit
;
2224 /* make sure setgroups dropped one */
2225 if ( my_orig_group_count
<= my_group_count
) {
2226 printf( "setgroups call failed. current group count is too high. \n" );
2227 goto test_failed_exit
;
2230 /* now put removed gid back */
2231 my_groups
[ (my_orig_group_count
- 1) ] = my_removed_gid
;
2232 my_err
= setgroups( my_orig_group_count
, &my_groups
[0] );
2233 if ( my_err
== -1 ) {
2234 printf( "setgroups call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2235 goto test_failed_exit
;
2238 /* find a group to change real and effective gid to then do it */
2240 for ( i
= 0; i
< my_orig_group_count
; i
++ ) {
2241 if ( my_groups
[i
] == my_effective_gid
|| my_groups
[i
] == my_real_gid
)
2243 my_new_gid
= my_groups
[i
];
2246 if ( my_new_gid
== -1 ) {
2247 printf( "could not find a gid to switch to. \n" );
2248 goto test_failed_exit
;
2252 my_err
= setegid( my_new_gid
);
2253 if ( my_err
== -1 ) {
2254 printf( "setegid call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2255 goto test_failed_exit
;
2257 /* verify it changed */
2258 if ( getegid( ) != my_new_gid
) {
2259 printf( "setegid failed to change the effective gid. \n" );
2260 goto test_failed_exit
;
2262 /* change it back to original value */
2263 my_err
= setegid( my_effective_gid
);
2264 if ( my_err
== -1 ) {
2265 printf( "setegid call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2266 goto test_failed_exit
;
2270 my_err
= setgid( my_new_gid
);
2271 if ( my_err
== -1 ) {
2272 printf( "setgid call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2273 goto test_failed_exit
;
2275 /* verify it changed */
2276 if ( getgid( ) != my_new_gid
) {
2277 printf( "setgid failed to change the real gid. \n" );
2278 goto test_failed_exit
;
2280 /* change it back to original value */
2281 my_err
= setgid( my_real_gid
);
2282 if ( my_err
== -1 ) {
2283 printf( "setegid call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2284 goto test_failed_exit
;
2288 goto test_passed_exit
;
2298 /* **************************************************************************************************************
2299 * Test dup, dup2, getdtablesize system calls.
2300 * **************************************************************************************************************
2302 int dup_test( void * the_argp
)
2307 int my_table_size
, my_loop_counter
= 0;
2308 char * my_pathp
= NULL
;
2311 kern_return_t my_kr
;
2313 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
2314 if(my_kr
!= KERN_SUCCESS
){
2315 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2316 goto test_failed_exit
;
2320 strcat( my_pathp
, &g_target_path
[0] );
2321 strcat( my_pathp
, "/" );
2323 /* create a test file */
2324 my_err
= create_random_name( my_pathp
, 1 );
2325 if ( my_err
!= 0 ) {
2326 goto test_failed_exit
;
2329 /* test dup, dup2, getdtablesize */
2330 my_table_size
= getdtablesize( );
2331 if ( my_table_size
< 20 ) {
2332 printf( "getdtablesize should return at least 20, returned %d \n", my_table_size
);
2333 goto test_failed_exit
;
2336 my_fd
= open( my_pathp
, O_RDWR
, 0 );
2337 if ( my_fd
== -1 ) {
2338 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2339 goto test_failed_exit
;
2342 my_newfd
= dup( my_fd
);
2343 if ( my_newfd
== -1 ) {
2344 printf( "dup call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2345 goto test_failed_exit
;
2349 /* now write somne data to the orginal and new fd */
2350 /* make sure test file is empty */
2351 my_err
= ftruncate( my_fd
, 0 );
2352 if ( my_err
== -1 ) {
2353 printf( "ftruncate call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2354 goto test_failed_exit
;
2357 lseek( my_fd
, 0, SEEK_SET
);
2358 my_count
= write( my_fd
, "aa", 2 );
2359 if ( my_count
== -1 ) {
2360 printf( "write call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2361 goto test_failed_exit
;
2364 my_count
= write( my_newfd
, "xx", 2 );
2365 if ( my_count
== -1 ) {
2366 printf( "write call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
2367 goto test_failed_exit
;
2370 /* now read it back and make sure data is correct */
2371 lseek( my_fd
, 0, SEEK_SET
);
2372 my_count
= read( my_fd
, &my_buffer
[0], sizeof(my_buffer
) );
2373 if ( my_count
== -1 ) {
2374 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2375 goto test_failed_exit
;
2377 if ( my_buffer
[0] != 'a' || my_buffer
[1] != 'a' || my_buffer
[2] != 'x' || my_buffer
[3] != 'x' ) {
2378 printf( "wrong data in test file. \n" );
2379 goto test_failed_exit
;
2382 bzero( &my_buffer
[0], sizeof(my_buffer
) );
2383 lseek( my_newfd
, 0, SEEK_SET
);
2384 my_count
= read( my_newfd
, &my_buffer
[0], sizeof(my_buffer
) );
2385 if ( my_count
== -1 ) {
2386 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2387 goto test_failed_exit
;
2389 if ( my_buffer
[0] != 'a' || my_buffer
[1] != 'a' || my_buffer
[2] != 'x' || my_buffer
[3] != 'x' ) {
2390 printf( "wrong data in test file. \n" );
2391 goto test_failed_exit
;
2394 /* we do the above tests twice - once for dup and once for dup2 */
2395 if ( my_loop_counter
< 1 ) {
2399 my_err
= dup2( my_fd
, my_newfd
);
2400 if ( my_err
== -1 ) {
2401 printf( "dup2 call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2402 goto test_failed_exit
;
2409 goto test_passed_exit
;
2417 if ( my_newfd
!= -1 )
2419 if ( my_pathp
!= NULL
) {
2421 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
2427 /* **************************************************************************************************************
2428 * Test getrusage system call.
2429 * **************************************************************************************************************
2431 int getrusage_test( void * the_argp
)
2434 struct rusage my_rusage
;
2436 my_err
= getrusage( RUSAGE_SELF
, &my_rusage
);
2437 if ( my_err
== -1 ) {
2438 printf( "getrusage failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2439 goto test_failed_exit
;
2442 /* do a sanity check on the getrusage results */
2443 if ( my_rusage
.ru_msgrcv
> 1000 || my_rusage
.ru_msgrcv
< 0 ) {
2444 printf( "getrusage seems to report wrong data - ru_msgrcv looks odd. \n" );
2445 goto test_failed_exit
;
2447 if ( my_rusage
.ru_nsignals
> 1000 || my_rusage
.ru_nsignals
< 0 ) {
2448 printf( "getrusage seems to report wrong data - ru_nsignals looks odd. \n" );
2449 goto test_failed_exit
;
2453 goto test_passed_exit
;
2462 /* **************************************************************************************************************
2463 * Test getitimer, setitimer, sigaction, sigpending, sigprocmask, sigsuspend, sigwait system calls.
2464 * **************************************************************************************************************
2467 int alarm_global
= 0;
2468 void test_alarm_handler( int the_arg
);
2469 void test_alarm_handler( int the_arg
)
2472 //printf( "test_alarm_handler - got here \n" );
2473 if ( the_arg
== 0 ) {
2478 void test_signal_handler( int the_arg
);
2479 void test_signal_handler( int the_arg
)
2481 //printf( "test_signal_handler - got here \n" );
2482 if ( the_arg
== 0 ) {
2487 int signals_test( void * the_argp
)
2489 int my_err
, my_status
;
2491 char * my_pathp
= NULL
;
2492 pid_t my_pid
, my_wait_pid
;
2493 kern_return_t my_kr
;
2495 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
2496 if(my_kr
!= KERN_SUCCESS
){
2497 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2498 goto test_failed_exit
;
2502 strcat( my_pathp
, &g_target_path
[0] );
2503 strcat( my_pathp
, "/" );
2505 /* create a test file */
2506 my_err
= create_random_name( my_pathp
, 1 );
2507 if ( my_err
!= 0 ) {
2508 goto test_failed_exit
;
2512 * spin off a child process that we will use for signal related testing.
2515 if ( my_pid
== -1 ) {
2516 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
2517 goto test_failed_exit
;
2519 if ( my_pid
== 0 ) {
2521 * child process - test signal related system calls.
2526 struct sigaction my_sigaction
;
2527 #ifdef MAC_OS_X_VERSION_10_5
2528 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
2529 /* If this is Leopard. To allow compiling for Inca x86_64 this definition cannot
2530 * be included. But it is needed to compile on Leopard.
2532 struct __darwin_sigaltstack my_sigaltstack
;
2535 struct sigaltstack my_sigaltstack
;
2537 struct itimerval my_timer
;
2540 /* test getting the current signal stack context */
2541 my_err
= sigaltstack( NULL
, &my_sigaltstack
);
2542 if ( my_err
== -1 ) {
2543 printf( "sigaction failed with errno %d - %s \n", errno
, strerror( errno
) );
2546 if ( (my_sigaltstack
.ss_flags
& SS_DISABLE
) == 0 ) {
2547 printf( "sigaction must have failed - SS_DISABLE is cleared \n" );
2551 /* set up to catch SIGUSR1 */
2552 my_sigaction
.sa_handler
= test_signal_handler
;
2553 my_sigaction
.sa_flags
= SA_RESTART
;
2554 my_sigaction
.sa_mask
= 0;
2556 my_err
= sigaction( SIGUSR1
, &my_sigaction
, NULL
);
2557 if ( my_err
== -1 ) {
2558 printf( "sigaction failed with errno %d - %s \n", errno
, strerror( errno
) );
2562 /* now suspend until signal SIGUSR1 is sent */
2563 sigemptyset( &my_sigset
);
2564 my_err
= sigsuspend( &my_sigset
);
2565 if ( my_err
== -1 ) {
2566 if ( errno
!= EINTR
) {
2567 printf( "sigsuspend should have returned with errno EINTR \n" );
2573 sigemptyset( &my_sigset
);
2574 sigaddset( &my_sigset
, SIGUSR1
);
2575 if ( sigismember( &my_sigset
, SIGUSR1
) == 0 ) {
2576 printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2579 my_err
= sigprocmask( SIG_BLOCK
, &my_sigset
, NULL
);
2580 if ( my_err
== -1 ) {
2581 printf( "sigprocmask failed with errno %d - %s \n", errno
, strerror( errno
) );
2585 /* make sure we are blocking SIGUSR1 */
2586 sigemptyset( &my_sigset
);
2587 my_err
= sigprocmask( 0, NULL
, &my_sigset
);
2588 if ( my_err
== -1 ) {
2589 printf( "sigprocmask failed with errno %d - %s \n", errno
, strerror( errno
) );
2592 if ( sigismember( &my_sigset
, SIGUSR1
) == 0 ) {
2593 printf( "sigaddset call failed to add SIGUSR1 to signal set \n" );
2597 /* our parent will send a 2nd SIGUSR1 signal which we should now see getting
2600 sigemptyset( &my_sigset
);
2601 sigaddset( &my_sigset
, SIGUSR1
);
2602 my_err
= sigwait( &my_sigset
, &my_signal
);
2603 if ( my_err
== -1 ) {
2604 printf( "sigwait failed with errno %d - %s \n", errno
, strerror( errno
) );
2607 //printf( "%s - %d - signal 0x%02X %d \n", __FUNCTION__, __LINE__, my_signal, my_signal );
2608 if ( my_signal
!= SIGUSR1
) {
2609 printf( "sigwait failed to catch a pending SIGUSR1 signal. \n" );
2613 /* now unblock SIGUSR1 */
2614 sigfillset( &my_sigset
);
2615 sigdelset( &my_sigset
, SIGUSR1
);
2616 my_err
= sigprocmask( SIG_UNBLOCK
, &my_sigset
, NULL
);
2617 if ( my_err
== -1 ) {
2618 printf( "sigprocmask failed with errno %d - %s \n", errno
, strerror( errno
) );
2621 if ( sigismember( &my_sigset
, SIGUSR1
) != 0 ) {
2622 printf( "sigprocmask call failed to unblock SIGUSR1 \n" );
2626 /* test get / setitimer */
2627 timerclear( &my_timer
.it_interval
);
2628 timerclear( &my_timer
.it_value
);
2629 my_err
= setitimer( ITIMER_VIRTUAL
, &my_timer
, NULL
);
2630 if ( my_err
== -1 ) {
2631 printf( "setitimer - ITIMER_VIRTUAL - failed with errno %d - %s \n", errno
, strerror( errno
) );
2634 my_err
= setitimer( ITIMER_PROF
, &my_timer
, NULL
);
2635 if ( my_err
== -1 ) {
2636 printf( "setitimer - ITIMER_PROF - failed with errno %d - %s \n", errno
, strerror( errno
) );
2640 /* set up to catch SIGALRM */
2642 my_sigaction
.sa_handler
= test_alarm_handler
;
2643 my_sigaction
.sa_flags
= SA_RESTART
;
2644 my_sigaction
.sa_mask
= 0;
2646 my_err
= sigaction( SIGALRM
, &my_sigaction
, NULL
);
2647 if ( my_err
== -1 ) {
2648 printf( "sigaction - SIGALRM - failed with errno %d - %s \n", errno
, strerror( errno
) );
2652 /* set timer for half a second */
2653 my_timer
.it_value
.tv_usec
= (1000000 / 2);
2654 my_err
= setitimer( ITIMER_REAL
, &my_timer
, NULL
);
2655 if ( my_err
== -1 ) {
2656 printf( "setitimer - ITIMER_REAL - failed with errno %d - %s \n", errno
, strerror( errno
) );
2660 /* now suspend until signal SIGALRM is sent */
2661 sigfillset( &my_sigset
);
2662 sigdelset( &my_sigset
, SIGALRM
);
2663 my_err
= sigsuspend( &my_sigset
);
2664 if ( my_err
== -1 ) {
2665 if ( errno
!= EINTR
) {
2666 printf( "sigsuspend should have returned with errno EINTR \n" );
2670 if ( alarm_global
!= 4 ) {
2671 printf( "setitimer test failed - did not catch SIGALRM \n" );
2675 /* make sure ITIMER_REAL is now clear */
2676 my_timer
.it_value
.tv_sec
= 44;
2677 my_timer
.it_value
.tv_usec
= 44;
2678 my_err
= getitimer( ITIMER_REAL
, &my_timer
);
2679 if ( my_err
== -1 ) {
2680 printf( "getitimer - ITIMER_REAL - failed with errno %d - %s \n", errno
, strerror( errno
) );
2683 if ( timerisset( &my_timer
.it_value
) || timerisset( &my_timer
.it_interval
) ) {
2684 printf( "ITIMER_REAL is set, but should not be \n" );
2692 * parent process - let child set up to suspend then signal it with SIGUSR1
2695 my_err
= kill( my_pid
, SIGUSR1
);
2696 if ( my_err
== -1 ) {
2697 printf( "kill call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2698 goto test_failed_exit
;
2701 /* send 2nd signal to suspended child - which should be blocking SIGUSR1 signals */
2703 my_err
= kill( my_pid
, SIGUSR1
);
2704 if ( my_err
== -1 ) {
2705 printf( "kill call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2706 goto test_failed_exit
;
2709 /* wait for child to exit */
2710 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
2711 if ( my_wait_pid
== -1 ) {
2712 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
2713 goto test_failed_exit
;
2716 if ( WIFSIGNALED( my_status
) || ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) ) {
2717 goto test_failed_exit
;
2721 goto test_passed_exit
;
2729 if ( my_pathp
!= NULL
) {
2731 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
2736 /* **************************************************************************************************************
2737 * Test getlogin, setlogin system calls.
2738 * **************************************************************************************************************
2740 int getlogin_setlogin_test( void * the_argp
)
2742 int my_err
, my_status
;
2743 pid_t my_pid
, my_wait_pid
;
2744 kern_return_t my_kr
;
2746 if ( g_skip_setuid_tests
!= 0 ) {
2747 printf("\t skipping this test \n");
2749 goto test_passed_exit
;
2753 * spin off a child process that we will use for testing.
2756 if ( my_pid
== -1 ) {
2757 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
2758 goto test_failed_exit
;
2760 if ( my_pid
== 0 ) {
2762 * child process - do getlogin and setlogin testing.
2764 char * my_namep
= NULL
;
2766 char * my_new_namep
= NULL
;
2768 my_namep
= getlogin( );
2769 if ( my_namep
== NULL
) {
2770 printf( "getlogin returned NULL name pointer \n" );
2775 my_len
= strlen( my_namep
) + 4;
2777 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_new_namep
, my_len
, VM_FLAGS_ANYWHERE
);
2778 if(my_kr
!= KERN_SUCCESS
){
2779 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2784 bzero( (void *)my_new_namep
, my_len
);
2786 strcat( my_new_namep
, my_namep
);
2787 strcat( my_new_namep
, "2" );
2791 my_err
= setlogin( my_new_namep
);
2792 if ( my_err
== -1 ) {
2793 printf( "When setting new login name, setlogin failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2798 /* make sure we set new name */
2799 my_namep
= getlogin( );
2800 if ( my_namep
== NULL
) {
2801 printf( "getlogin returned NULL name pointer \n" );
2806 if ( memcmp( my_namep
, my_new_namep
, strlen( my_new_namep
) ) != 0 ) {
2807 printf( "setlogin failed to set the new name \n" );
2812 /* reset to original name */
2813 my_len
= strlen ( my_namep
);
2814 my_namep
[ my_len
- 1 ] = '\0';
2816 my_err
= setlogin( my_namep
);
2817 if ( my_err
== -1 ) {
2818 printf( "When resetting login name, setlogin failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2826 if ( my_new_namep
!= NULL
) {
2827 vm_deallocate(mach_task_self(), (vm_address_t
)my_new_namep
, my_len
);
2833 * wait for child to exit
2835 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
2836 if ( my_wait_pid
== -1 ) {
2837 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
2838 goto test_failed_exit
;
2841 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) {
2842 goto test_failed_exit
;
2845 goto test_passed_exit
;
2854 /* **************************************************************************************************************
2855 * Test acct system call.
2856 * **************************************************************************************************************
2858 int acct_test( void * the_argp
)
2860 int my_err
, my_status
;
2862 char * my_pathp
= NULL
;
2863 struct acct
* my_acctp
;
2864 pid_t my_pid
, my_wait_pid
;
2866 char my_buffer
[ (sizeof(struct acct
) + 32) ];
2867 kern_return_t my_kr
;
2868 int acct_record_found
;
2869 char * test_bin_name
= NULL
;
2871 if ( g_skip_setuid_tests
!= 0 ) {
2872 printf("\t skipping this test \n");
2874 goto test_passed_exit
;
2877 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
2878 if(my_kr
!= KERN_SUCCESS
){
2879 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2880 goto test_failed_exit
;
2884 strcat( my_pathp
, &g_target_path
[0] );
2885 strcat( my_pathp
, "/" );
2887 /* create a test file */
2888 my_err
= create_random_name( my_pathp
, 1 );
2889 if ( my_err
!= 0 ) {
2890 goto test_failed_exit
;
2893 /* enable process accounting */
2894 my_err
= acct( my_pathp
);
2895 if ( my_err
== -1 ) {
2896 printf( "acct failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2897 goto test_failed_exit
;
2901 * spin off a child process that we will use for testing.
2904 if ( my_pid
== -1 ) {
2905 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
2906 goto test_failed_exit
;
2908 if ( my_pid
== 0 ) {
2909 char *argv
[2]; /* supply valid argv array to execv() */
2910 argv
[0] = "/usr/bin/true";
2914 * child process - do a little work then exit.
2916 my_err
= execv( argv
[0], argv
);
2921 * wait for child to exit
2923 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
2924 if ( my_wait_pid
== -1 ) {
2925 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
2926 goto test_failed_exit
;
2929 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) {
2930 printf("unexpected child exit status for accounting test load: %d\n", WEXITSTATUS( my_status
));
2931 goto test_failed_exit
;
2934 /* disable process accounting */
2935 my_err
= acct( NULL
);
2936 if ( my_err
== -1 ) {
2937 printf( "acct failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2938 goto test_failed_exit
;
2941 /* now verify that there is accounting info in the log file */
2942 my_fd
= open( my_pathp
, O_RDONLY
, 0 );
2943 if ( my_fd
== -1 ) {
2944 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2945 goto test_failed_exit
;
2948 lseek( my_fd
, 0, SEEK_SET
);
2949 bzero( (void *)&my_buffer
[0], sizeof(my_buffer
) );
2950 acct_record_found
= 0;
2951 test_bin_name
= "true";
2955 my_count
= read( my_fd
, &my_buffer
[0], sizeof(struct acct
) );
2957 if ( my_count
== -1 ) {
2958 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
2959 goto test_failed_exit
;
2962 if ( my_count
< sizeof(struct acct
)) {
2963 /* Indicates EOF or misaligned file size */
2964 printf("Reached end of accounting records with last read count: %d\n", my_count
);
2968 my_acctp
= (struct acct
*) &my_buffer
[0];
2969 /* first letters in ac_comm should match the name of the executable */
2970 if ( (getuid() == my_acctp
->ac_uid
) && (getgid() == my_acctp
->ac_gid
) &&
2971 (!strncmp(my_acctp
->ac_comm
, test_bin_name
, strlen(test_bin_name
))) ) {
2972 /* Expected accounting record found */
2973 acct_record_found
= 1;
2979 if (acct_record_found
) {
2981 goto test_passed_exit
;
2983 printf( "------------------------\n" );
2984 printf( "Expected Accounting Record for child process %s not found\n", test_bin_name
);
2985 printf( "Expected uid: %lu Expected gid: %lu\n" , (unsigned long) getuid(), (unsigned long) getgid() );
2986 printf( "Account file path: %s\n", my_pathp
);
2987 goto test_failed_exit
;
2996 if ( my_pathp
!= NULL
) {
2998 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
3003 void print_acct_debug_strings( char * my_ac_comm
)
3005 char my_cmd_str
[11]; /* sizeof(acct_cmd) + 1 for '\0' if acct_cmd is bogus */
3006 char my_hex_str
[128];
3009 my_hex_str
[0] = '\0';
3010 for(i
= 0; i
< 10; i
++)
3012 sprintf( my_hex_str
, "%s \'0x%x\' ", my_hex_str
, my_ac_comm
[i
]);
3015 memccpy(my_cmd_str
, my_ac_comm
, '\0', 10);
3016 my_cmd_str
[10] = '\0'; /* In case ac_comm was bogus */
3019 printf( "my_acctp->ac_comm = \"%s\" (should begin with: \"tr\")\n", my_cmd_str
);
3020 printf( "my_acctp->ac_comm = \"%s\"\n", my_hex_str
);
3021 printf( "------------------------\n" );
3025 /* **************************************************************************************************************
3026 * Test ioctl system calls.
3027 * **************************************************************************************************************
3029 int ioctl_test( void * the_argp
)
3031 int my_err
, my_result
;
3033 struct statfs
* my_infop
;
3036 long long my_block_count
;
3037 char my_name
[ 128 ];
3039 my_result
= getmntinfo( &my_infop
, MNT_NOWAIT
);
3040 if ( my_result
< 1 ) {
3041 printf( "getmntinfo failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3042 goto test_failed_exit
;
3045 /* make this a raw device */
3046 strcpy( &my_name
[0], &my_infop
->f_mntfromname
[0] );
3047 if ( (my_ptr
= strrchr( &my_name
[0], '/' )) != 0 ) {
3048 if ( my_ptr
[1] != 'r' ) {
3049 my_ptr
[ strlen( my_ptr
) ] = 0x00;
3050 memmove( &my_ptr
[2], &my_ptr
[1], (strlen( &my_ptr
[1] ) + 1) );
3055 my_fd
= open(&my_name
[0], O_RDONLY
);
3056 if ( my_fd
== -1 ) {
3057 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3058 goto test_failed_exit
;
3061 /* obtain the size of the media (in blocks) */
3062 my_err
= ioctl( my_fd
, DKIOCGETBLOCKCOUNT
, &my_block_count
);
3063 if ( my_err
== -1 ) {
3064 printf( "ioctl DKIOCGETBLOCKCOUNT failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3065 goto test_failed_exit
;
3068 /* obtain the block size of the media */
3069 my_err
= ioctl( my_fd
, DKIOCGETBLOCKSIZE
, &my_blksize
);
3070 if ( my_err
== -1 ) {
3071 printf( "ioctl DKIOCGETBLOCKSIZE failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3072 goto test_failed_exit
;
3074 //printf( "my_block_count %qd my_blksize %d \n", my_block_count, my_blksize );
3076 /* make sure the returned data looks somewhat valid */
3077 if ( my_blksize
< 0 || my_blksize
> (1024 * 1000) ) {
3078 printf( "ioctl appears to have returned incorrect block size data \n" );
3079 goto test_failed_exit
;
3083 goto test_passed_exit
;
3094 /* **************************************************************************************************************
3095 * Test mkdir, rmdir, umask system calls.
3096 * **************************************************************************************************************
3098 int mkdir_rmdir_umask_test( void * the_argp
)
3103 char * my_pathp
= NULL
;
3104 mode_t my_orig_mask
;
3106 kern_return_t my_kr
;
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
;
3115 strcat( my_pathp
, &g_target_path
[0] );
3116 strcat( my_pathp
, "/" );
3118 /* get a unique name to use with mkdir */
3119 my_err
= create_random_name( my_pathp
, 0 );
3120 if ( my_err
!= 0 ) {
3121 printf( "create_random_name failed with error %d\n", my_err
);
3122 goto test_failed_exit
;
3125 /* set umask to clear WX for other and group and clear X for user */
3126 my_orig_mask
= umask( (S_IXUSR
| S_IWGRP
| S_IXGRP
| S_IWOTH
| S_IXOTH
) );
3129 /* create a directory with RWX for user, group, other (which should be limited by umask) */
3130 my_err
= mkdir( my_pathp
, (S_IRWXU
| S_IRWXG
| S_IRWXO
) );
3131 if ( my_err
== -1 ) {
3132 printf( "mkdir failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3133 goto test_failed_exit
;
3136 /* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/
3137 my_err
= stat( my_pathp
, &my_sb
);
3138 if ( my_err
!= 0 ) {
3139 printf( "stat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3140 goto test_failed_exit
;
3142 if ( (my_sb
.st_mode
& (S_IXUSR
| S_IWGRP
| S_IXGRP
| S_IWOTH
| S_IXOTH
)) != 0 ) {
3143 printf( "umask did not limit modes as it should have \n" );
3144 goto test_failed_exit
;
3147 /* get rid of our test directory */
3148 my_err
= rmdir( my_pathp
);
3149 if ( my_err
== -1 ) {
3150 printf( "rmdir failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3151 goto test_failed_exit
;
3154 goto test_passed_exit
;
3162 if ( my_pathp
!= NULL
) {
3164 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
3166 if ( did_umask
!= 0 ) {
3167 umask( my_orig_mask
);
3173 /* **************************************************************************************************************
3174 * Test chroot system call.
3175 * **************************************************************************************************************
3177 int chroot_test( void * the_argp
)
3179 int my_err
, my_status
;
3180 pid_t my_pid
, my_wait_pid
;
3181 char * my_pathp
= NULL
;
3182 kern_return_t my_kr
;
3184 if ( g_skip_setuid_tests
!= 0 ) {
3185 printf("\t skipping this test \n");
3187 goto test_passed_exit
;
3190 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
3191 if(my_kr
!= KERN_SUCCESS
){
3192 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3193 goto test_failed_exit
;
3197 strcat( my_pathp
, &g_target_path
[0] );
3198 strcat( my_pathp
, "/" );
3200 /* get a unique name for our test directory */
3201 my_err
= create_random_name( my_pathp
, 0 );
3202 if ( my_err
!= 0 ) {
3203 goto test_failed_exit
;
3206 /* create a test directory */
3207 my_err
= mkdir( my_pathp
, (S_IRWXU
| S_IRWXG
| S_IRWXO
) );
3208 if ( my_err
== -1 ) {
3209 printf( "mkdir failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3210 goto test_failed_exit
;
3214 * spin off a child process that we will use for testing.
3217 if ( my_pid
== -1 ) {
3218 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
3219 goto test_failed_exit
;
3221 if ( my_pid
== 0 ) {
3223 * child process - do getlogin and setlogin testing.
3227 /* change our root to our new test directory */
3228 my_err
= chroot( my_pathp
);
3229 if ( my_err
!= 0 ) {
3230 printf( "chroot failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3234 /* verify root directory is now an empty directory */
3235 my_err
= stat( "/", &my_sb
);
3236 if ( my_err
!= 0 ) {
3237 printf( "stat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3240 if ( my_sb
.st_nlink
> 2 ) {
3241 printf( "root dir should be emnpty! \n" );
3248 * wait for child to exit
3250 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
3251 if ( my_wait_pid
== -1 ) {
3252 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
3253 goto test_failed_exit
;
3256 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) {
3257 printf( "bad exit status\n" );
3258 goto test_failed_exit
;
3262 goto test_passed_exit
;
3268 if ( my_pathp
!= NULL
) {
3269 my_err
= rmdir( my_pathp
);
3270 if ( my_err
!= 0 ) {
3271 printf( "rmdir failed with error %d - \"%s\" path %p\n", errno
, strerror( errno
), my_pathp
);
3273 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
3278 /* **************************************************************************************************************
3279 * Test getpgrp, getpgid, getsid, setpgid, setpgrp, setsid system calls.
3280 * **************************************************************************************************************
3282 int process_group_test( void * the_argp
)
3284 int my_err
= 0, i
= 0;
3285 pid_t my_session_id
, my_pid
, my_process_group
;
3287 /* get current session ID, pgid, and pid */
3288 my_session_id
= getsid( 0 );
3289 if ( my_session_id
== -1 ) {
3290 printf( "getsid call failed with error %d - \"%s\" \n",
3291 errno
, strerror( errno
) );
3292 goto test_failed_exit
;
3296 my_process_group
= getpgrp( );
3298 /* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */
3299 if ( my_process_group
!= getpgid( 0 ) ) {
3300 printf( "getpgrp and getpgid did not return the same process group ID \n" );
3301 printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group
);
3302 goto test_failed_exit
;
3305 if ( my_pid
== my_process_group
) {
3306 /* we are process group leader */
3308 if ( my_err
== 0 || errno
!= EPERM
) {
3309 printf( "setsid call should have failed with EPERM\n" );
3310 goto test_failed_exit
;
3313 /* we are not process group leader: try creating new session */
3315 if ( my_err
== -1 ) {
3316 printf( "setsid call failed with error %d - \"%s\" \n",
3317 errno
, strerror( errno
) );
3318 goto test_failed_exit
;
3321 if ( my_process_group
== getpgid( 0 ) ) {
3322 printf( "process group was not reset \n" );
3323 goto test_failed_exit
;
3327 /* find an unused process group ID */
3328 for ( i
= 10000; i
< 1000000; i
++ ) {
3329 my_process_group
= getpgid( i
);
3330 if ( my_process_group
== -1 ) {
3335 /* this should fail */
3336 my_err
= setpgid( 0, my_process_group
);
3337 if ( my_err
!= -1 ) {
3338 printf( "setpgid should have failed, but did not \n" );
3339 goto test_failed_exit
;
3343 goto test_passed_exit
;
3352 /* **************************************************************************************************************
3353 * Test fcntl system calls.
3354 * **************************************************************************************************************
3356 int fcntl_test( void * the_argp
)
3358 int my_err
, my_result
, my_tmep
;
3361 char * my_pathp
= NULL
;
3362 kern_return_t my_kr
;
3364 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
3365 if(my_kr
!= KERN_SUCCESS
){
3366 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3367 goto test_failed_exit
;
3371 strcat( my_pathp
, &g_target_path
[0] );
3372 strcat( my_pathp
, "/" );
3374 /* create a test file */
3375 my_err
= create_random_name( my_pathp
, 1 );
3376 if ( my_err
!= 0 ) {
3377 goto test_failed_exit
;
3380 /* open our test file and use fcntl to get / set file descriptor flags */
3381 my_fd
= open( my_pathp
, O_RDONLY
, 0 );
3382 if ( my_fd
== -1 ) {
3383 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3384 goto test_failed_exit
;
3387 my_result
= fcntl( my_fd
, F_GETFD
, 0 );
3388 if ( my_result
== -1 ) {
3389 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3390 goto test_failed_exit
;
3393 my_tmep
= (my_result
& FD_CLOEXEC
);
3395 /* FD_CLOEXEC is on, let's turn it off */
3396 my_result
= fcntl( my_fd
, F_SETFD
, 0 );
3399 /* FD_CLOEXEC is off, let's turn it on */
3400 my_result
= fcntl( my_fd
, F_SETFD
, 1 );
3402 if ( my_result
== -1 ) {
3403 printf( "fcntl - F_SETFD - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3404 goto test_failed_exit
;
3407 /* now check to see if it is set correctly */
3408 my_result
= fcntl( my_fd
, F_GETFD
, 0 );
3409 if ( my_result
== -1 ) {
3410 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3411 goto test_failed_exit
;
3413 if ( my_tmep
== (my_result
& 0x01) ) {
3414 printf( "fcntl - F_SETFD failed to set FD_CLOEXEC correctly!!! \n" );
3415 goto test_failed_exit
;
3418 /* dup it to a new fd with FD_CLOEXEC forced on */
3420 my_result
= fcntl( my_fd
, F_DUPFD_CLOEXEC
, 0);
3421 if ( my_result
== -1 ) {
3422 printf( "fcntl - F_DUPFD_CLOEXEC - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3423 goto test_failed_exit
;
3425 my_newfd
= my_result
;
3427 /* check to see that it too is marked with FD_CLOEXEC */
3429 my_result
= fcntl( my_newfd
, F_GETFD
, 0);
3430 if ( my_result
== -1 ) {
3431 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3432 goto test_failed_exit
;
3434 if ( (my_result
& FD_CLOEXEC
) == 0 ) {
3435 printf( "fcntl - F_DUPFD_CLOEXEC failed to set FD_CLOEXEC!!! \n" );
3436 goto test_failed_exit
;
3442 /* While we're here, dup it via an open of /dev/fd/<fd> .. */
3445 char devfdpath
[PATH_MAX
];
3447 (void) snprintf( devfdpath
, sizeof (devfdpath
),
3448 "/dev/fd/%u", my_fd
);
3449 my_result
= open( devfdpath
, O_RDONLY
| O_CLOEXEC
);
3451 if ( my_result
== -1 ) {
3452 printf( "open call failed on /dev/fd/%u with error %d - \"%s\" \n", my_fd
, errno
, strerror( errno
) );
3453 goto test_failed_exit
;
3455 my_newfd
= my_result
;
3457 /* check to see that it too is marked with FD_CLOEXEC */
3459 my_result
= fcntl( my_newfd
, F_GETFD
, 0);
3460 if ( my_result
== -1 ) {
3461 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3462 goto test_failed_exit
;
3464 if ( (my_result
& FD_CLOEXEC
) == 0 ) {
3465 printf( "fcntl - O_CLOEXEC open of /dev/fd/%u failed to set FD_CLOEXEC!!! \n", my_fd
);
3466 goto test_failed_exit
;
3471 goto test_passed_exit
;
3477 if ( my_newfd
!= -1)
3481 if ( my_pathp
!= NULL
) {
3483 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
3488 /* **************************************************************************************************************
3489 * Test getpriority, setpriority system calls.
3490 * **************************************************************************************************************
3492 int getpriority_setpriority_test( void * the_argp
)
3496 int my_new_priority
;
3498 /* getpriority returns scheduling priority so -1 is a valid value */
3500 my_priority
= getpriority( PRIO_PROCESS
, 0 );
3501 if ( my_priority
== -1 && errno
!= 0 ) {
3502 printf( "getpriority - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3503 goto test_failed_exit
;
3506 /* change scheduling priority */
3507 my_new_priority
= (my_priority
== PRIO_MIN
) ? (my_priority
+ 10) : (PRIO_MIN
);
3508 my_err
= setpriority( PRIO_PROCESS
, 0, my_new_priority
);
3509 if ( my_err
== -1 ) {
3510 printf( "setpriority - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3511 goto test_failed_exit
;
3516 my_priority
= getpriority( PRIO_PROCESS
, 0 );
3517 if ( my_priority
== -1 && errno
!= 0 ) {
3518 printf( "getpriority - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3519 goto test_failed_exit
;
3522 if ( my_priority
!= my_new_priority
) {
3523 printf( "setpriority - failed to set correct scheduling priority \n" );
3524 goto test_failed_exit
;
3527 /* reset scheduling priority */
3528 my_err
= setpriority( PRIO_PROCESS
, 0, 0 );
3529 if ( my_err
== -1 ) {
3530 printf( "setpriority - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3531 goto test_failed_exit
;
3535 goto test_passed_exit
;
3544 /* **************************************************************************************************************
3545 * Test futimes, gettimeofday, settimeofday, utimes system calls.
3546 * **************************************************************************************************************
3548 int time_tests( void * the_argp
)
3552 char * my_pathp
= NULL
;
3553 struct timeval my_orig_time
;
3554 struct timeval my_temp_time
;
3555 struct timeval my_utimes
[4];
3556 struct timezone my_tz
;
3558 kern_return_t my_kr
;
3560 if ( g_skip_setuid_tests
!= 0 ) {
3561 printf( "\t skipping this test \n" );
3563 goto test_passed_exit
;
3566 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
3567 if(my_kr
!= KERN_SUCCESS
){
3568 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3569 goto test_failed_exit
;
3573 strcat( my_pathp
, &g_target_path
[0] );
3574 strcat( my_pathp
, "/" );
3576 /* create a test file */
3577 my_err
= create_random_name( my_pathp
, 1 );
3578 if ( my_err
!= 0 ) {
3579 goto test_failed_exit
;
3582 my_err
= gettimeofday( &my_orig_time
, &my_tz
);
3583 if ( my_err
== -1 ) {
3584 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3585 goto test_failed_exit
;
3587 //printf( "tv_sec %d tv_usec %ld \n", my_orig_time.tv_sec, my_orig_time.tv_usec );
3589 my_temp_time
= my_orig_time
;
3590 my_temp_time
.tv_sec
-= 60;
3591 my_err
= settimeofday( &my_temp_time
, NULL
);
3592 if ( my_err
== -1 ) {
3593 printf( "settimeofday - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3594 goto test_failed_exit
;
3597 my_err
= gettimeofday( &my_temp_time
, NULL
);
3598 if ( my_err
== -1 ) {
3599 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3600 goto test_failed_exit
;
3602 //printf( "tv_sec %d tv_usec %ld \n", my_temp_time.tv_sec, my_temp_time.tv_usec );
3603 if ( my_orig_time
.tv_sec
<= my_temp_time
.tv_sec
) {
3604 printf( "settimeofday did not set correct time \n" );
3605 goto test_failed_exit
;
3608 /* set time back to original value plus 1 second */
3609 my_temp_time
= my_orig_time
;
3610 my_temp_time
.tv_sec
+= 1;
3611 my_err
= settimeofday( &my_temp_time
, NULL
);
3612 if ( my_err
== -1 ) {
3613 printf( "settimeofday - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3614 goto test_failed_exit
;
3617 /* test utimes and futimes - get current access and mod times then change them */
3618 my_err
= stat( my_pathp
, &my_sb
);
3619 if ( my_err
!= 0 ) {
3620 printf( "stat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3621 goto test_failed_exit
;
3623 TIMESPEC_TO_TIMEVAL( &my_utimes
[0], &my_sb
.st_atimespec
);
3624 TIMESPEC_TO_TIMEVAL( &my_utimes
[1], &my_sb
.st_mtimespec
);
3625 my_utimes
[0].tv_sec
-= 120; /* make access time 2 minutes older */
3626 my_utimes
[1].tv_sec
-= 120; /* make mod time 2 minutes older */
3628 my_err
= utimes( my_pathp
, &my_utimes
[0] );
3629 if ( my_err
== -1 ) {
3630 printf( "utimes - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3631 goto test_failed_exit
;
3634 /* make sure the correct times are set */
3635 my_err
= stat( my_pathp
, &my_sb
);
3636 if ( my_err
!= 0 ) {
3637 printf( "stat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3638 goto test_failed_exit
;
3640 TIMESPEC_TO_TIMEVAL( &my_utimes
[2], &my_sb
.st_atimespec
);
3641 TIMESPEC_TO_TIMEVAL( &my_utimes
[3], &my_sb
.st_mtimespec
);
3642 if ( my_utimes
[0].tv_sec
!= my_utimes
[2].tv_sec
||
3643 my_utimes
[1].tv_sec
!= my_utimes
[3].tv_sec
) {
3644 printf( "utimes failed to set access and mod times \n" );
3645 goto test_failed_exit
;
3648 my_fd
= open( my_pathp
, O_RDWR
, 0 );
3649 if ( my_fd
== -1 ) {
3650 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3651 goto test_failed_exit
;
3654 my_utimes
[0].tv_sec
-= 120; /* make access time 2 minutes older */
3655 my_utimes
[1].tv_sec
-= 120; /* make mod time 2 minutes older */
3656 my_err
= futimes( my_fd
, &my_utimes
[0] );
3657 if ( my_err
== -1 ) {
3658 printf( "futimes - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3659 goto test_failed_exit
;
3662 /* make sure the correct times are set */
3663 my_err
= stat( my_pathp
, &my_sb
);
3664 if ( my_err
!= 0 ) {
3665 printf( "stat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3666 goto test_failed_exit
;
3668 TIMESPEC_TO_TIMEVAL( &my_utimes
[2], &my_sb
.st_atimespec
);
3669 TIMESPEC_TO_TIMEVAL( &my_utimes
[3], &my_sb
.st_mtimespec
);
3670 if ( my_utimes
[0].tv_sec
!= my_utimes
[2].tv_sec
||
3671 my_utimes
[1].tv_sec
!= my_utimes
[3].tv_sec
) {
3672 printf( "futimes failed to set access and mod times \n" );
3673 goto test_failed_exit
;
3677 goto test_passed_exit
;
3685 if ( my_pathp
!= NULL
) {
3687 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
3692 /* **************************************************************************************************************
3693 * Test rename, stat system calls.
3694 * **************************************************************************************************************
3696 int rename_test( void * the_argp
)
3699 char * my_pathp
= NULL
;
3700 char * my_new_pathp
= NULL
;
3703 kern_return_t my_kr
;
3705 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
3706 if(my_kr
!= KERN_SUCCESS
){
3707 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3708 goto test_failed_exit
;
3712 strcat( my_pathp
, &g_target_path
[0] );
3713 strcat( my_pathp
, "/" );
3715 /* create a test file */
3716 my_err
= create_random_name( my_pathp
, 1 );
3717 if ( my_err
!= 0 ) {
3718 goto test_failed_exit
;
3721 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_new_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
3722 if(my_kr
!= KERN_SUCCESS
){
3723 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3724 goto test_failed_exit
;
3727 *my_new_pathp
= 0x00;
3728 strcat( my_new_pathp
, &g_target_path
[0] );
3729 strcat( my_new_pathp
, "/" );
3731 /* get a unique name for our rename test */
3732 my_err
= create_random_name( my_new_pathp
, 0 );
3733 if ( my_err
!= 0 ) {
3734 goto test_failed_exit
;
3737 /* save file ID for later use */
3738 my_err
= stat( my_pathp
, &my_sb
);
3739 if ( my_err
!= 0 ) {
3740 printf( "stat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3741 goto test_failed_exit
;
3743 my_file_id
= my_sb
.st_ino
;
3746 my_err
= rename( my_pathp
, my_new_pathp
);
3747 if ( my_err
== -1 ) {
3748 printf( "rename - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3749 goto test_failed_exit
;
3752 /* make sure old name is no longer there */
3753 my_err
= stat( my_pathp
, &my_sb
);
3754 if ( my_err
== 0 ) {
3755 printf( "rename call failed - found old name \n" );
3756 goto test_failed_exit
;
3759 /* make sure new name is there and is correct file id */
3760 my_err
= stat( my_new_pathp
, &my_sb
);
3761 if ( my_err
!= 0 ) {
3762 printf( "stat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3763 goto test_failed_exit
;
3765 if ( my_file_id
!= my_sb
.st_ino
) {
3766 printf( "rename failed - wrong file id \n" );
3767 goto test_failed_exit
;
3771 goto test_passed_exit
;
3777 if ( my_pathp
!= NULL
) {
3779 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
3781 if ( my_new_pathp
!= NULL
) {
3782 remove( my_new_pathp
);
3783 vm_deallocate(mach_task_self(), (vm_address_t
)my_new_pathp
, PATH_MAX
);
3788 /* **************************************************************************************************************
3789 * Test locking system calls.
3790 * **************************************************************************************************************
3792 int locking_test( void * the_argp
)
3794 int my_err
, my_status
;
3795 pid_t my_pid
, my_wait_pid
;
3797 char * my_pathp
= NULL
;
3798 kern_return_t my_kr
;
3800 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
3801 if(my_kr
!= KERN_SUCCESS
){
3802 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3803 goto test_failed_exit
;
3807 strcat( my_pathp
, &g_target_path
[0] );
3808 strcat( my_pathp
, "/" );
3810 /* create a test file */
3811 my_err
= create_random_name( my_pathp
, 1 );
3812 if ( my_err
!= 0 ) {
3813 goto test_failed_exit
;
3817 my_fd
= open( my_pathp
, O_RDWR
, 0 );
3818 if ( my_fd
== -1 ) {
3819 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3820 goto test_failed_exit
;
3823 my_err
= flock( my_fd
, LOCK_EX
);
3824 if ( my_err
== -1 ) {
3825 printf( "flock - LOCK_EX - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3826 goto test_failed_exit
;
3830 * spin off a child process that we will use for testing.
3833 if ( my_pid
== -1 ) {
3834 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
3835 goto test_failed_exit
;
3837 if ( my_pid
== 0 ) {
3841 int my_child_fd
= -1;
3844 my_child_fd
= open( my_pathp
, O_RDWR
, 0 );
3845 if ( my_child_fd
== -1 ) {
3846 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3851 my_err
= flock( my_child_fd
, (LOCK_EX
| LOCK_NB
) );
3852 if ( my_err
== -1 ) {
3853 if ( errno
!= EWOULDBLOCK
) {
3854 printf( "flock call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3860 printf( "flock call should have failed with EWOULDBLOCK err \n" );
3866 if ( my_child_fd
!= -1 )
3867 close( my_child_fd
);
3868 exit( my_child_err
);
3872 * wait for child to exit
3874 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
3875 if ( my_wait_pid
== -1 ) {
3876 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
3877 goto test_failed_exit
;
3880 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) {
3881 goto test_failed_exit
;
3884 my_err
= flock( my_fd
, LOCK_UN
);
3885 if ( my_err
== -1 ) {
3886 printf( "flock - LOCK_UN - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3887 goto test_failed_exit
;
3891 goto test_passed_exit
;
3899 if ( my_pathp
!= NULL
) {
3901 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
3906 /* **************************************************************************************************************
3907 * Test mkfifo system calls.
3908 * **************************************************************************************************************
3910 int mkfifo_test( void * the_argp
)
3912 int my_err
, my_status
;
3913 pid_t my_pid
, my_wait_pid
;
3915 char * my_pathp
= NULL
;
3917 off_t my_current_offset
;
3918 kern_return_t my_kr
;
3920 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
3921 if(my_kr
!= KERN_SUCCESS
){
3922 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3923 goto test_failed_exit
;
3927 strcat( my_pathp
, &g_target_path
[0] );
3928 strcat( my_pathp
, "/" );
3930 /* get unique name for our fifo */
3931 my_err
= create_random_name( my_pathp
, 0 );
3932 if ( my_err
!= 0 ) {
3933 goto test_failed_exit
;
3936 my_err
= mkfifo( my_pathp
, (S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) );
3937 if ( my_err
!= 0 ) {
3938 printf( "mkfifo failed with errno %d - %s. \n", errno
, strerror( errno
) );
3939 goto test_failed_exit
;
3943 * spin off a child process that we will use for testing.
3946 if ( my_pid
== -1 ) {
3947 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
3948 goto test_failed_exit
;
3950 if ( my_pid
== 0 ) {
3954 int my_child_fd
= -1;
3958 /* open read end of fifo */
3959 my_child_fd
= open( my_pathp
, O_RDWR
, 0 );
3960 if ( my_child_fd
== -1 ) {
3961 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3966 /* read message from parent */
3967 bzero( (void *)&my_buffer
[0], sizeof(my_buffer
) );
3968 my_result
= read( my_child_fd
, &my_buffer
[0], sizeof(my_buffer
) );
3969 if ( my_result
== -1 ) {
3970 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3974 if ( strcmp( "parent to child", &my_buffer
[0] ) != 0 ) {
3975 printf( "read wrong message from parent \n" );
3982 if ( my_child_fd
!= -1 )
3983 close( my_child_fd
);
3984 exit( my_child_err
);
3987 /* parent process - open write end of fifo
3989 my_fd
= open( my_pathp
, O_WRONLY
, 0 );
3990 if ( my_fd
== -1 ) {
3991 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
3992 goto test_failed_exit
;
3995 /* make sure we can't seek on a fifo */
3996 my_current_offset
= lseek( my_fd
, 0, SEEK_CUR
);
3997 if ( my_current_offset
!= -1 ) {
3998 printf( "lseek on fifo should fail but did not \n" );
3999 goto test_failed_exit
;
4002 my_result
= write( my_fd
, "parent to child", 15 );
4003 if ( my_result
== -1 ) {
4004 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4005 goto test_failed_exit
;
4008 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
4009 if ( my_wait_pid
== -1 ) {
4010 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
4011 goto test_failed_exit
;
4014 if ( WIFEXITED( my_status
) && WEXITSTATUS( my_status
) != 0 ) {
4015 goto test_failed_exit
;
4019 goto test_passed_exit
;
4027 if ( my_pathp
!= NULL
) {
4029 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
4034 /* **************************************************************************************************************
4035 * Test quotactl system calls.
4036 * **************************************************************************************************************
4038 int quotactl_test( void * the_argp
)
4041 int is_quotas_on
= 0;
4042 struct dqblk my_quota_blk
;
4044 if ( g_skip_setuid_tests
!= 0 ) {
4045 printf( "\t skipping this test \n" );
4047 goto test_passed_exit
;
4050 /* start off by checking the status of quotas on the boot volume */
4051 my_err
= quotactl( "/System/Library/Kernels/kernel", QCMD(Q_QUOTASTAT
, USRQUOTA
), 0, (caddr_t
)&is_quotas_on
);
4052 if ( my_err
== -1 ) {
4053 printf( "quotactl - Q_QUOTASTAT - failed with errno %d - %s \n", errno
, strerror( errno
) );
4054 goto test_failed_exit
;
4057 if ( is_quotas_on
== 0 ) {
4058 /* quotas are off */
4060 goto test_passed_exit
;
4063 my_err
= quotactl( "/System/Library/Kernels/kernel", QCMD(Q_GETQUOTA
, USRQUOTA
), getuid(), (caddr_t
)&my_quota_blk
);
4064 if ( my_err
== -1 ) {
4065 printf( "quotactl - Q_GETQUOTA - failed with errno %d - %s \n", errno
, strerror( errno
) );
4066 goto test_failed_exit
;
4070 goto test_passed_exit
;
4079 /* **************************************************************************************************************
4080 * Test getrlimit, setrlimit system calls.
4081 * **************************************************************************************************************
4083 int limit_tests( void * the_argp
)
4086 struct rlimit my_current_rlimit
;
4087 struct rlimit my_rlimit
;
4089 my_err
= getrlimit( RLIMIT_NOFILE
, &my_current_rlimit
);
4090 if ( my_err
== -1 ) {
4091 printf( "getrlimit - failed with errno %d - %s \n", errno
, strerror( errno
) );
4092 goto test_failed_exit
;
4094 if ( my_current_rlimit
.rlim_cur
!= RLIM_INFINITY
) {
4095 if ( my_current_rlimit
.rlim_cur
!= my_current_rlimit
.rlim_max
)
4096 my_current_rlimit
.rlim_cur
+= 1;
4098 my_current_rlimit
.rlim_cur
-= 1;
4099 my_rlimit
.rlim_cur
= my_current_rlimit
.rlim_cur
;
4100 my_rlimit
.rlim_max
= my_current_rlimit
.rlim_max
;
4101 my_err
= setrlimit( RLIMIT_NOFILE
, &my_rlimit
);
4102 if ( my_err
== -1 ) {
4103 printf( "setrlimit - failed with errno %d - %s \n", errno
, strerror( errno
) );
4104 goto test_failed_exit
;
4107 /* verify that we set a new limit */
4108 bzero( (void *) &my_rlimit
, sizeof( my_rlimit
) );
4109 my_err
= getrlimit( RLIMIT_NOFILE
, &my_rlimit
);
4110 if ( my_err
== -1 ) {
4111 printf( "getrlimit - failed with errno %d - %s \n", errno
, strerror( errno
) );
4112 goto test_failed_exit
;
4114 if ( my_rlimit
.rlim_cur
!= my_current_rlimit
.rlim_cur
) {
4115 printf( "failed to get/set new RLIMIT_NOFILE soft limit \n" );
4116 printf( "soft limits - current %lld should be %lld \n", my_rlimit
.rlim_cur
, my_current_rlimit
.rlim_cur
);
4117 goto test_failed_exit
;
4120 #if CONFORMANCE_CHANGES_IN_XNU // can't do this check until conformance changes get into xnu
4121 printf( "hard limits - current %lld should be %lld \n", my_rlimit
.rlim_max
, my_current_rlimit
.rlim_max
);
4122 if ( my_rlimit
.rlim_max
!= my_current_rlimit
.rlim_max
) {
4123 printf( "failed to get/set new RLIMIT_NOFILE hard limit \n" );
4124 goto test_failed_exit
;
4129 * A test for a limit that won't fit in a signed 32 bits, a la 5414697
4130 * Note: my_rlimit should still have a valid rlim_max.
4132 long long biglim
= 2147483649ll; /* Just over 2^31 */
4133 my_rlimit
.rlim_cur
= biglim
;
4134 my_err
= setrlimit(RLIMIT_CPU
, &my_rlimit
);
4136 printf("failed to set large limit.\n");
4137 goto test_failed_exit
;
4140 bzero(&my_rlimit
, sizeof(struct rlimit
));
4141 my_err
= getrlimit(RLIMIT_CPU
, &my_rlimit
);
4143 printf("after setting large value, failed to getrlimit().\n");
4144 goto test_failed_exit
;
4147 if (my_rlimit
.rlim_cur
!= biglim
) {
4148 printf("didn't retrieve large limit.\n");
4149 goto test_failed_exit
;
4154 goto test_passed_exit
;
4163 /* **************************************************************************************************************
4164 * Test getattrlist, getdirentriesattr, setattrlist system calls.
4165 * **************************************************************************************************************
4167 struct test_attr_buf
{
4169 fsobj_type_t obj_type
;
4171 struct timespec backup_time
;
4174 typedef struct test_attr_buf test_attr_buf
;
4176 int directory_tests( void * the_argp
)
4178 int my_err
, done
, found_it
, i
;
4181 char * my_pathp
= NULL
;
4182 char * my_bufp
= NULL
;
4183 char * my_file_namep
;
4185 unsigned int my_base
;
4186 unsigned int my_count
;
4187 unsigned int my_new_state
;
4189 unsigned long my_base
;
4190 unsigned long my_count
;
4191 unsigned long my_new_state
;
4193 fsobj_id_t my_obj_id
;
4194 struct timespec my_new_backup_time
;
4195 struct attrlist my_attrlist
;
4196 test_attr_buf my_attr_buf
[4];
4197 struct statfs my_statfs_buf
;
4198 kern_return_t my_kr
;
4200 /* need to know type of file system */
4201 my_err
= statfs( &g_target_path
[0], &my_statfs_buf
);
4202 if ( my_err
== -1 ) {
4203 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
4204 goto test_failed_exit
;
4206 if ( memcmp( &my_statfs_buf
.f_fstypename
[0], "ufs", 3 ) == 0 ) {
4210 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_bufp
, (1024 * 5), VM_FLAGS_ANYWHERE
);
4211 if(my_kr
!= KERN_SUCCESS
){
4212 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4213 goto test_failed_exit
;
4216 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
4217 if(my_kr
!= KERN_SUCCESS
){
4218 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4219 goto test_failed_exit
;
4223 strcat( my_pathp
, &g_target_path
[0] );
4224 strcat( my_pathp
, "/" );
4226 /* create a test file */
4227 my_err
= create_random_name( my_pathp
, 1 );
4228 if ( my_err
!= 0 ) {
4229 goto test_failed_exit
;
4232 /* get pointer to just the file name */
4233 my_file_namep
= strrchr( my_pathp
, '/' );
4236 /* check out the test directory */
4237 my_fd
= open( &g_target_path
[0], (O_RDONLY
), 0 );
4238 if ( my_fd
== -1 ) {
4239 printf( "open failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4240 goto test_failed_exit
;
4243 /* test get/setattrlist */
4244 memset( &my_attrlist
, 0, sizeof(my_attrlist
) );
4245 my_attrlist
.bitmapcount
= ATTR_BIT_MAP_COUNT
;
4246 my_attrlist
.commonattr
= (ATTR_CMN_OBJTYPE
| ATTR_CMN_OBJID
| ATTR_CMN_BKUPTIME
);
4247 my_err
= getattrlist( my_pathp
, &my_attrlist
, &my_attr_buf
[0], sizeof(my_attr_buf
[0]), 0 );
4249 if ( my_err
!= 0 ) {
4250 if ( errno
== ENOTSUP
&& is_ufs
) {
4251 /* getattr calls not supported on ufs */
4253 goto test_passed_exit
;
4255 printf( "getattrlist call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
4256 goto test_failed_exit
;
4258 /* validate returned data */
4259 if ( my_attr_buf
[0].obj_type
!= VREG
) {
4260 printf( "getattrlist returned incorrect obj_type data. \n" );
4261 goto test_failed_exit
;
4264 /* set new backup time */
4265 my_obj_id
= my_attr_buf
[0].obj_id
;
4266 my_new_backup_time
= my_attr_buf
[0].backup_time
;
4267 my_new_backup_time
.tv_sec
+= 60;
4268 my_attr_buf
[0].backup_time
.tv_sec
= my_new_backup_time
.tv_sec
;
4269 my_attrlist
.commonattr
= (ATTR_CMN_BKUPTIME
);
4270 my_err
= setattrlist( my_pathp
, &my_attrlist
, &my_attr_buf
[0].backup_time
, sizeof(my_attr_buf
[0].backup_time
), 0 );
4271 if ( my_err
!= 0 ) {
4272 printf( "setattrlist call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
4273 goto test_failed_exit
;
4276 /* validate setattrlist using getdirentriesattr */
4278 my_fd
= open( &g_target_path
[0], (O_RDONLY
), 0 );
4279 if ( my_fd
== -1 ) {
4280 printf( "open failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4281 goto test_failed_exit
;
4283 memset( &my_attrlist
, 0, sizeof(my_attrlist
) );
4284 memset( &my_attr_buf
, 0, sizeof(my_attr_buf
) );
4285 my_attrlist
.bitmapcount
= ATTR_BIT_MAP_COUNT
;
4286 my_attrlist
.commonattr
= (ATTR_CMN_OBJTYPE
| ATTR_CMN_OBJID
| ATTR_CMN_BKUPTIME
);
4289 my_err
= getdirentriesattr( my_fd
, &my_attrlist
, &my_attr_buf
[0], sizeof(my_attr_buf
), &my_count
,
4290 &my_base
, &my_new_state
, 0 );
4292 printf( "getdirentriesattr call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
4293 goto test_failed_exit
;
4297 for ( i
= 0; i
< my_count
; i
++ ) {
4298 if ( my_attr_buf
[i
].obj_id
.fid_objno
== my_obj_id
.fid_objno
&&
4299 my_attr_buf
[i
].obj_id
.fid_generation
== my_obj_id
.fid_generation
) {
4301 if ( my_attr_buf
[i
].backup_time
.tv_sec
!= my_new_backup_time
.tv_sec
) {
4302 printf( "setattrlist failed to set backup time. \n" );
4303 goto test_failed_exit
;
4307 if ( found_it
== 0 ) {
4308 printf( "getdirentriesattr failed to find test file. \n" );
4309 goto test_failed_exit
;
4313 goto test_passed_exit
;
4322 if ( my_pathp
!= NULL
) {
4324 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
4326 if ( my_bufp
!= NULL
) {
4327 vm_deallocate(mach_task_self(), (vm_address_t
)my_bufp
, (1024 * 5));
4332 /* **************************************************************************************************************
4333 * Test exchangedata system calls.
4334 * **************************************************************************************************************
4336 int exchangedata_test( void * the_argp
)
4341 char * my_file1_pathp
= NULL
;
4342 char * my_file2_pathp
= NULL
;
4345 struct statfs my_statfs_buf
;
4346 kern_return_t my_kr
;
4348 /* need to know type of file system */
4349 my_err
= statfs( &g_target_path
[0], &my_statfs_buf
);
4350 if ( my_err
== -1 ) {
4351 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
4352 goto test_failed_exit
;
4354 if ( memcmp( &my_statfs_buf
.f_fstypename
[0], "ufs", 3 ) == 0 ) {
4355 /* ufs does not support exchangedata */
4357 goto test_passed_exit
;
4360 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_file1_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
4361 if(my_kr
!= KERN_SUCCESS
){
4362 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4363 goto test_failed_exit
;
4366 *my_file1_pathp
= 0x00;
4367 strcat( my_file1_pathp
, &g_target_path
[0] );
4368 strcat( my_file1_pathp
, "/" );
4370 /* create a test file */
4371 my_err
= create_random_name( my_file1_pathp
, 1 );
4372 if ( my_err
!= 0 ) {
4373 printf( "create_random_name my_err: %d\n", my_err
);
4374 goto test_failed_exit
;
4376 my_fd1
= open( my_file1_pathp
, O_RDWR
, 0 );
4377 if ( my_fd1
== -1 ) {
4378 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4379 goto test_failed_exit
;
4381 my_result
= write( my_fd1
, "11111111", 8 );
4382 if ( my_result
== -1 ) {
4383 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4384 goto test_failed_exit
;
4387 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_file2_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
4388 if(my_kr
!= KERN_SUCCESS
){
4389 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4390 goto test_failed_exit
;
4393 *my_file2_pathp
= 0x00;
4394 strcat( my_file2_pathp
, &g_target_path
[0] );
4395 strcat( my_file2_pathp
, "/" );
4397 /* create a test file */
4398 my_err
= create_random_name( my_file2_pathp
, 1 );
4399 if ( my_err
!= 0 ) {
4400 printf( "create_random_name my_err: %d\n", my_err
);
4401 goto test_failed_exit
;
4403 my_fd2
= open( my_file2_pathp
, O_RDWR
, 0 );
4404 if ( my_fd2
== -1 ) {
4405 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4406 goto test_failed_exit
;
4408 my_result
= write( my_fd2
, "22222222", 8 );
4409 if ( my_result
== -1 ) {
4410 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4411 goto test_failed_exit
;
4418 /* test exchangedata */
4419 my_err
= exchangedata( my_file1_pathp
, my_file2_pathp
, 0 );
4420 if ( my_err
== -1 ) {
4421 printf( "exchangedata failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4422 goto test_failed_exit
;
4425 /* now validate exchange */
4426 my_fd1
= open( my_file1_pathp
, O_RDONLY
, 0 );
4427 if ( my_fd1
== -1 ) {
4428 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4429 goto test_failed_exit
;
4431 bzero( (void *)&my_buffer
[0], sizeof(my_buffer
) );
4432 my_result
= read( my_fd1
, &my_buffer
[0], 8 );
4433 if ( my_result
== -1 ) {
4434 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4435 goto test_failed_exit
;
4438 if ( memcmp( &my_buffer
[0], "22222222", 8 ) != 0 ) {
4439 printf( "exchangedata failed - incorrect data in file \n" );
4440 goto test_failed_exit
;
4444 goto test_passed_exit
;
4452 if ( my_file1_pathp
!= NULL
) {
4453 remove( my_file1_pathp
);
4454 vm_deallocate(mach_task_self(), (vm_address_t
)my_file1_pathp
, PATH_MAX
);
4458 if ( my_file2_pathp
!= NULL
) {
4459 remove( my_file2_pathp
);
4460 vm_deallocate(mach_task_self(), (vm_address_t
)my_file2_pathp
, PATH_MAX
);
4466 /* **************************************************************************************************************
4467 * Test searchfs system calls.
4468 * **************************************************************************************************************
4471 struct packed_name_attr
{
4472 u_int32_t size
; /* Of the remaining fields */
4473 struct attrreference ref
; /* Offset/length of name itself */
4474 char name
[ PATH_MAX
];
4477 struct packed_attr_ref
{
4478 u_int32_t size
; /* Of the remaining fields */
4479 struct attrreference ref
; /* Offset/length of attr itself */
4482 struct packed_result
{
4483 u_int32_t size
; /* Including size field itself */
4484 attrreference_t obj_name
;
4485 struct fsobj_id obj_id
;
4486 struct timespec obj_create_time
;
4487 char room_for_name
[ 64 ];
4489 typedef struct packed_result packed_result
;
4490 typedef struct packed_result
* packed_result_p
;
4492 #define MAX_MATCHES 10
4493 #define MAX_EBUSY_RETRIES 20
4495 int searchfs_test( void * the_argp
)
4497 int my_err
, my_items_found
= 0, my_ebusy_count
;
4498 char * my_pathp
= NULL
;
4499 unsigned long my_matches
;
4500 unsigned long my_search_options
;
4501 struct fssearchblock my_search_blk
;
4502 struct attrlist my_return_list
;
4503 struct searchstate my_search_state
;
4504 struct packed_name_attr my_info1
;
4505 struct packed_attr_ref my_info2
;
4506 packed_result my_result_buffer
[ MAX_MATCHES
];
4507 struct statfs my_statfs_buf
;
4508 kern_return_t my_kr
;
4510 /* need to know type of file system */
4511 my_err
= statfs( &g_target_path
[0], &my_statfs_buf
);
4512 if ( my_err
== -1 ) {
4513 printf( "statfs call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
4514 goto test_failed_exit
;
4516 if ( memcmp( &my_statfs_buf
.f_fstypename
[0], "ufs", 3 ) == 0 ) {
4517 /* ufs does not support exchangedata */
4519 goto test_passed_exit
;
4522 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
4523 if(my_kr
!= KERN_SUCCESS
){
4524 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4525 goto test_failed_exit
;
4529 strcat( my_pathp
, &g_target_path
[0] );
4530 strcat( my_pathp
, "/" );
4532 /* create test files */
4533 my_err
= create_file_with_name( my_pathp
, "foo", 0 );
4535 printf( "failed to create a test file name in \"%s\" \n", my_pathp
);
4536 goto test_failed_exit
;
4539 my_err
= create_file_with_name( my_pathp
, "foobar", 0 );
4541 printf( "failed to create a test file name in \"%s\" \n", my_pathp
);
4542 goto test_failed_exit
;
4545 my_err
= create_file_with_name( my_pathp
, "foofoo", 0 );
4547 printf( "failed to create a test file name in \"%s\" \n", my_pathp
);
4548 goto test_failed_exit
;
4551 my_err
= create_file_with_name( my_pathp
, "xxxfoo", 0 );
4553 printf( "failed to create a test file name in \"%s\" \n", my_pathp
);
4554 goto test_failed_exit
;
4557 /* EBUSY count updated below the catalogue_changed label */
4561 /* search target volume for all file system objects with "foo" in the name */
4562 /* Set up the attributes we're searching on. */
4563 my_items_found
= 0; /* Set this here in case we're completely restarting */
4564 my_search_blk
.searchattrs
.bitmapcount
= ATTR_BIT_MAP_COUNT
;
4565 my_search_blk
.searchattrs
.reserved
= 0;
4566 my_search_blk
.searchattrs
.commonattr
= ATTR_CMN_NAME
;
4567 my_search_blk
.searchattrs
.volattr
= 0;
4568 my_search_blk
.searchattrs
.dirattr
= 0;
4569 my_search_blk
.searchattrs
.fileattr
= 0;
4570 my_search_blk
.searchattrs
.forkattr
= 0;
4572 /* Set up the attributes we want for all returned matches. */
4573 /* Why is returnattrs a pointer instead of an embedded struct? */
4574 my_search_blk
.returnattrs
= &my_return_list
;
4575 my_return_list
.bitmapcount
= ATTR_BIT_MAP_COUNT
;
4576 my_return_list
.reserved
= 0;
4577 my_return_list
.commonattr
= ATTR_CMN_NAME
| ATTR_CMN_OBJID
| ATTR_CMN_CRTIME
;
4578 my_return_list
.volattr
= 0;
4579 my_return_list
.dirattr
= 0;
4580 my_return_list
.fileattr
= 0;
4581 my_return_list
.forkattr
= 0;
4583 /* Allocate a buffer for returned matches */
4584 my_search_blk
.returnbuffer
= my_result_buffer
;
4585 my_search_blk
.returnbuffersize
= sizeof(my_result_buffer
);
4587 /* Pack the searchparams1 into a buffer */
4588 /* NOTE: A name appears only in searchparams1 */
4589 strcpy( my_info1
.name
, "foo" );
4590 my_info1
.ref
.attr_dataoffset
= sizeof(struct attrreference
);
4591 my_info1
.ref
.attr_length
= strlen(my_info1
.name
) + 1;
4592 my_info1
.size
= sizeof(struct attrreference
) + my_info1
.ref
.attr_length
;
4593 my_search_blk
.searchparams1
= &my_info1
;
4594 my_search_blk
.sizeofsearchparams1
= my_info1
.size
+ sizeof(u_int32_t
);
4596 /* Pack the searchparams2 into a buffer */
4597 my_info2
.size
= sizeof(struct attrreference
);
4598 my_info2
.ref
.attr_dataoffset
= sizeof(struct attrreference
);
4599 my_info2
.ref
.attr_length
= 0;
4600 my_search_blk
.searchparams2
= &my_info2
;
4601 my_search_blk
.sizeofsearchparams2
= sizeof(my_info2
);
4603 /* Maximum number of matches we want */
4604 my_search_blk
.maxmatches
= MAX_MATCHES
;
4606 /* Maximum time to search, per call */
4607 my_search_blk
.timelimit
.tv_sec
= 1;
4608 my_search_blk
.timelimit
.tv_usec
= 0;
4610 my_search_options
= (SRCHFS_START
| SRCHFS_MATCHPARTIALNAMES
|
4611 SRCHFS_MATCHFILES
| SRCHFS_MATCHDIRS
);
4617 my_err
= searchfs( my_pathp
, &my_search_blk
, &my_matches
, 0, my_search_options
, &my_search_state
);
4620 if ( (my_err
== 0 || my_err
== EAGAIN
) && my_matches
> 0 ) {
4621 /* Unpack the results */
4622 // printf("my_matches %d \n", my_matches);
4623 my_ptr
= (char *) &my_result_buffer
[0];
4624 my_end_ptr
= (my_ptr
+ sizeof(my_result_buffer
));
4625 for ( i
= 0; i
< my_matches
; ++i
) {
4626 packed_result_p my_result_p
= (packed_result_p
) my_ptr
;
4629 /* see if we foound all our test files */
4630 my_name_p
= (((char *)(&my_result_p
->obj_name
)) + my_result_p
->obj_name
.attr_dataoffset
);
4631 if ( memcmp( my_name_p
, "foo", 3 ) == 0 ||
4632 memcmp( my_name_p
, "foobar", 6 ) == 0 ||
4633 memcmp( my_name_p
, "foofoo", 6 ) == 0 ||
4634 memcmp( my_name_p
, "xxxfoo", 6 ) == 0 ) {
4638 printf("obj_name \"%.*s\" \n",
4639 (int) my_result_p
->obj_name
.attr_length
,
4640 (((char *)(&my_result_p
->obj_name
)) +
4641 my_result_p
->obj_name
.attr_dataoffset
));
4642 printf("size %d fid_objno %d fid_generation %d tv_sec 0x%02LX \n",
4643 my_result_p
->size
, my_result_p
->obj_id
.fid_objno
,
4644 my_result_p
->obj_id
.fid_generation
,
4645 my_result_p
->obj_create_time
.tv_sec
);
4647 my_ptr
= (my_ptr
+ my_result_p
->size
);
4648 if (my_ptr
> my_end_ptr
)
4653 /* EBUSY indicates catalogue change; retry a few times. */
4654 if ((my_err
== EBUSY
) && (my_ebusy_count
++ < MAX_EBUSY_RETRIES
)) {
4655 goto catalogue_changed
;
4657 if ( !(my_err
== 0 || my_err
== EAGAIN
) ) {
4658 printf( "searchfs failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4660 my_search_options
&= ~SRCHFS_START
;
4661 } while ( my_err
== EAGAIN
);
4663 if ( my_items_found
< 4 ) {
4664 printf( "searchfs failed to find all test files \n" );
4665 goto test_failed_exit
;
4669 goto test_passed_exit
;
4675 if ( my_pathp
!= NULL
) {
4676 char * my_ptr
= (my_pathp
+ strlen( my_pathp
));
4677 strcat( my_pathp
, "foo" );
4680 strcat( my_pathp
, "foobar" );
4683 strcat( my_pathp
, "foofoo" );
4686 strcat( my_pathp
, "xxxfoo" );
4688 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
4694 #define AIO_TESTS_BUFFER_SIZE (1024 * 4000)
4695 #define AIO_TESTS_OUR_COUNT 5
4696 /* **************************************************************************************************************
4697 * Test aio_error, aio_read, aio_return, aio_suspend, aio_write, fcntl system calls.
4698 * **************************************************************************************************************
4700 int aio_tests( void * the_argp
)
4704 struct aiocb
* my_aiocbp
;
4706 struct timespec my_timeout
;
4707 int my_fd_list
[ AIO_TESTS_OUR_COUNT
];
4708 char * my_buffers
[ AIO_TESTS_OUR_COUNT
];
4709 struct aiocb
* my_aiocb_list
[ AIO_TESTS_OUR_COUNT
];
4710 struct aiocb my_aiocbs
[ AIO_TESTS_OUR_COUNT
];
4711 char * my_file_paths
[ AIO_TESTS_OUR_COUNT
];
4712 kern_return_t my_kr
;
4714 /* set up to have the ability to fire off up to AIO_TESTS_OUR_COUNT async IOs at once */
4715 memset( &my_fd_list
[0], 0xFF, sizeof( my_fd_list
) );
4716 memset( &my_buffers
[0], 0x00, sizeof( my_buffers
) );
4717 memset( &my_aiocb_list
[0], 0x00, sizeof( my_aiocb_list
) );
4718 memset( &my_file_paths
[0], 0x00, sizeof( my_file_paths
) );
4719 for ( i
= 0; i
< AIO_TESTS_OUR_COUNT
; i
++ ) {
4720 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_buffers
[ i
], AIO_TESTS_BUFFER_SIZE
, VM_FLAGS_ANYWHERE
);
4721 if(my_kr
!= KERN_SUCCESS
){
4722 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4723 goto test_failed_exit
;
4726 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_file_paths
[ i
], PATH_MAX
, VM_FLAGS_ANYWHERE
);
4727 if(my_kr
!= KERN_SUCCESS
){
4728 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4729 goto test_failed_exit
;
4732 my_pathp
= my_file_paths
[ i
];
4734 strcat( my_pathp
, &g_target_path
[0] );
4735 strcat( my_pathp
, "/" );
4737 /* create a test file */
4738 my_err
= create_random_name( my_pathp
, 1 );
4739 if ( my_err
!= 0 ) {
4740 goto test_failed_exit
;
4742 my_fd_list
[ i
] = open( my_pathp
, O_RDWR
, 0 );
4743 if ( my_fd_list
[ i
] <= 0 ) {
4744 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4745 goto test_failed_exit
;
4748 my_aiocbp
= &my_aiocbs
[ i
];
4749 my_aiocb_list
[ i
] = my_aiocbp
;
4750 memset( my_aiocbp
, 0x00, sizeof( *my_aiocbp
) );
4751 my_aiocbp
->aio_fildes
= my_fd_list
[ i
];
4752 my_aiocbp
->aio_buf
= (char *) my_buffers
[ i
];
4753 my_aiocbp
->aio_nbytes
= 1024;
4754 my_aiocbp
->aio_sigevent
.sigev_notify
= SIGEV_NONE
; // no signals at completion;
4755 my_aiocbp
->aio_sigevent
.sigev_signo
= 0;
4758 /* test direct IO (F_NOCACHE) and aio_write */
4759 my_err
= fcntl( my_fd_list
[ 0 ], F_NOCACHE
, 1 );
4760 if ( my_err
!= 0 ) {
4761 printf( "malloc failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4762 goto test_failed_exit
;
4765 my_aiocbp
= &my_aiocbs
[ 0 ];
4766 my_aiocbp
->aio_fildes
= my_fd_list
[ 0 ];
4767 my_aiocbp
->aio_offset
= 4096;
4768 my_aiocbp
->aio_buf
= my_buffers
[ 0 ];
4769 my_aiocbp
->aio_nbytes
= AIO_TESTS_BUFFER_SIZE
;
4770 my_aiocbp
->aio_reqprio
= 0;
4771 my_aiocbp
->aio_sigevent
.sigev_notify
= 0;
4772 my_aiocbp
->aio_sigevent
.sigev_signo
= 0;
4773 my_aiocbp
->aio_sigevent
.sigev_value
.sival_int
= 0;
4774 my_aiocbp
->aio_sigevent
.sigev_notify_function
= NULL
;
4775 my_aiocbp
->aio_sigevent
.sigev_notify_attributes
= NULL
;
4776 my_aiocbp
->aio_lio_opcode
= 0;
4778 /* write some data */
4779 memset( my_buffers
[ 0 ], 'j', AIO_TESTS_BUFFER_SIZE
);
4780 my_err
= aio_write( my_aiocbp
);
4781 if ( my_err
!= 0 ) {
4782 printf( "aio_write failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4783 goto test_failed_exit
;
4787 my_err
= aio_error( my_aiocbp
);
4788 if ( my_err
== EINPROGRESS
) {
4789 /* wait for IO to complete */
4793 else if ( my_err
== 0 ) {
4795 my_result
= aio_return( my_aiocbp
);
4799 printf( "aio_error failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4800 goto test_failed_exit
;
4804 /* read some data */
4805 memset( my_buffers
[ 0 ], 'x', AIO_TESTS_BUFFER_SIZE
);
4806 my_err
= aio_read( my_aiocbp
);
4809 my_err
= aio_error( my_aiocbp
);
4810 if ( my_err
== EINPROGRESS
) {
4811 /* wait for IO to complete */
4815 else if ( my_err
== 0 ) {
4817 my_result
= aio_return( my_aiocbp
);
4819 if ( *(my_buffers
[ 0 ]) != 'j' || *(my_buffers
[ 0 ] + AIO_TESTS_BUFFER_SIZE
- 1) != 'j' ) {
4820 printf( "aio_read or aio_write failed - wrong data read \n" );
4821 goto test_failed_exit
;
4826 printf( "aio_read failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4827 goto test_failed_exit
;
4831 /* test aio_fsync */
4832 close( my_fd_list
[ 0 ] );
4833 my_fd_list
[ 0 ] = open( my_pathp
, O_RDWR
, 0 );
4834 if ( my_fd_list
[ 0 ] == -1 ) {
4835 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4836 goto test_failed_exit
;
4839 my_aiocbp
= &my_aiocbs
[ 0 ];
4840 my_aiocbp
->aio_fildes
= my_fd_list
[ 0 ];
4841 my_aiocbp
->aio_offset
= 0;
4842 my_aiocbp
->aio_buf
= my_buffers
[ 0 ];
4843 my_aiocbp
->aio_nbytes
= 1024;
4844 my_aiocbp
->aio_reqprio
= 0;
4845 my_aiocbp
->aio_sigevent
.sigev_notify
= 0;
4846 my_aiocbp
->aio_sigevent
.sigev_signo
= 0;
4847 my_aiocbp
->aio_sigevent
.sigev_value
.sival_int
= 0;
4848 my_aiocbp
->aio_sigevent
.sigev_notify_function
= NULL
;
4849 my_aiocbp
->aio_sigevent
.sigev_notify_attributes
= NULL
;
4850 my_aiocbp
->aio_lio_opcode
= 0;
4852 /* write some data */
4853 memset( my_buffers
[ 0 ], 'e', 1024 );
4854 my_err
= aio_write( my_aiocbp
);
4855 if ( my_err
!= 0 ) {
4856 printf( "aio_write failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4857 goto test_failed_exit
;
4860 my_err
= aio_error( my_aiocbp
);
4861 if ( my_err
== EINPROGRESS
) {
4862 /* wait for IO to complete */
4866 else if ( my_err
== 0 ) {
4868 my_result
= aio_return( my_aiocbp
);
4872 printf( "aio_error failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4873 goto test_failed_exit
;
4877 my_err
= aio_fsync( O_SYNC
, my_aiocbp
);
4878 if ( my_err
!= 0 ) {
4879 printf( "aio_fsync failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4880 goto test_failed_exit
;
4883 my_err
= aio_error( my_aiocbp
);
4884 if ( my_err
== EINPROGRESS
) {
4885 /* wait for IO to complete */
4889 else if ( my_err
== 0 ) {
4890 aio_return( my_aiocbp
);
4894 printf( "aio_error failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4895 goto test_failed_exit
;
4899 /* validate write */
4900 memset( my_buffers
[ 0 ], 0x20, 16 );
4901 lseek( my_fd_list
[ 0 ], 0, SEEK_SET
);
4902 my_result
= read( my_fd_list
[ 0 ], my_buffers
[ 0 ], 16);
4903 if ( my_result
== -1 ) {
4904 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4905 goto test_failed_exit
;
4907 if ( *(my_buffers
[ 0 ]) != 'e' || *(my_buffers
[ 0 ] + 16 - 1) != 'e' ) {
4908 printf( "aio_fsync or aio_write failed - wrong data read \n" );
4909 goto test_failed_exit
;
4912 /* test aio_suspend and lio_listio */
4913 for ( i
= 0; i
< AIO_TESTS_OUR_COUNT
; i
++ ) {
4914 memset( my_buffers
[ i
], 'a', AIO_TESTS_BUFFER_SIZE
);
4915 my_aiocbp
= &my_aiocbs
[ i
];
4916 my_aiocbp
->aio_nbytes
= AIO_TESTS_BUFFER_SIZE
;
4917 my_aiocbp
->aio_lio_opcode
= LIO_WRITE
;
4919 my_err
= lio_listio( LIO_NOWAIT
, my_aiocb_list
, AIO_TESTS_OUR_COUNT
, NULL
);
4920 if ( my_err
!= 0 ) {
4921 printf( "lio_listio call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4922 goto test_failed_exit
;
4925 my_timeout
.tv_sec
= 1;
4926 my_timeout
.tv_nsec
= 0;
4927 my_err
= aio_suspend( (const struct aiocb
*const*) my_aiocb_list
, AIO_TESTS_OUR_COUNT
, &my_timeout
);
4928 if ( my_err
!= 0 ) {
4929 printf( "aio_suspend call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
4930 goto test_failed_exit
;
4933 /* test aio_cancel */
4934 for ( i
= 0; i
< AIO_TESTS_OUR_COUNT
; i
++ ) {
4935 my_aiocbp
= &my_aiocbs
[ i
];
4936 my_err
= aio_cancel( my_aiocbp
->aio_fildes
, my_aiocbp
);
4937 if ( my_err
!= AIO_ALLDONE
&& my_err
!= AIO_CANCELED
&& my_err
!= AIO_NOTCANCELED
) {
4938 printf( "aio_cancel failed with error %d - \"%s\" \n", my_err
, strerror( my_err
) );
4939 goto test_failed_exit
;
4944 goto test_passed_exit
;
4950 for ( i
= 0; i
< AIO_TESTS_OUR_COUNT
; i
++ ) {
4951 if ( my_fd_list
[ i
] != -1 ) {
4952 close( my_fd_list
[ i
] );
4953 my_fd_list
[ i
] = -1;
4955 if ( my_file_paths
[ i
] != NULL
) {
4956 remove( my_file_paths
[ i
] );
4957 vm_deallocate(mach_task_self(), (vm_address_t
)my_file_paths
[ i
], PATH_MAX
);
4958 my_file_paths
[ i
] = NULL
;
4960 if ( my_buffers
[ i
] != NULL
) {
4961 vm_deallocate(mach_task_self(), (vm_address_t
)my_buffers
[ i
], AIO_TESTS_BUFFER_SIZE
);
4962 my_buffers
[ i
] = NULL
;
4969 /* **************************************************************************************************************
4970 * Test msgctl, msgget, msgrcv, msgsnd system calls.
4971 * **************************************************************************************************************
4973 int message_queue_tests( void * the_argp
)
4976 int my_msg_queue_id
= -1;
4978 struct msqid_ds my_msq_ds
;
4979 struct testing_msq_message
{
4981 char msq_buffer
[ 32 ];
4984 /* get a message queue established for our use */
4985 my_msg_queue_id
= msgget( IPC_PRIVATE
, (IPC_CREAT
| IPC_EXCL
| IPC_R
| IPC_W
) );
4986 if ( my_msg_queue_id
== -1 ) {
4987 printf( "msgget failed with errno %d - %s \n", errno
, strerror( errno
) );
4988 goto test_failed_exit
;
4991 /* get some stats on our message queue */
4992 my_err
= msgctl( my_msg_queue_id
, IPC_STAT
, &my_msq_ds
);
4993 if ( my_err
== -1 ) {
4994 printf( "msgctl failed with errno %d - %s \n", errno
, strerror( errno
) );
4995 goto test_failed_exit
;
4997 if ( my_msq_ds
.msg_perm
.cuid
!= geteuid( ) ) {
4998 printf( "msgctl IPC_STAT failed to get correct creator uid \n" );
4999 goto test_failed_exit
;
5001 if ( (my_msq_ds
.msg_perm
.mode
& (IPC_R
| IPC_W
)) == 0 ) {
5002 printf( "msgctl IPC_STAT failed to get correct mode \n" );
5003 goto test_failed_exit
;
5006 /* put a message into our queue */
5007 my_msg
.msq_type
= 1;
5008 strcpy( &my_msg
.msq_buffer
[ 0 ], "testing 1, 2, 3" );
5009 my_err
= msgsnd( my_msg_queue_id
, &my_msg
, sizeof( my_msg
.msq_buffer
), 0 );
5010 if ( my_err
== -1 ) {
5011 printf( "msgsnd failed with errno %d - %s \n", errno
, strerror( errno
) );
5012 goto test_failed_exit
;
5015 my_err
= msgctl( my_msg_queue_id
, IPC_STAT
, &my_msq_ds
);
5016 if ( my_err
== -1 ) {
5017 printf( "msgctl failed with errno %d - %s \n", errno
, strerror( errno
) );
5018 goto test_failed_exit
;
5020 if ( my_msq_ds
.msg_qnum
!= 1 ) {
5021 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5022 goto test_failed_exit
;
5025 /* pull message off the queue */
5026 bzero( (void *)&my_msg
, sizeof( my_msg
) );
5027 my_result
= msgrcv( my_msg_queue_id
, &my_msg
, sizeof( my_msg
.msq_buffer
), 0, 0 );
5028 if ( my_result
== -1 ) {
5029 printf( "msgrcv failed with errno %d - %s \n", errno
, strerror( errno
) );
5030 goto test_failed_exit
;
5032 if ( my_result
!= sizeof( my_msg
.msq_buffer
) ) {
5033 printf( "msgrcv failed to return the correct number of bytes in our buffer \n" );
5034 goto test_failed_exit
;
5036 if ( strcmp( &my_msg
.msq_buffer
[ 0 ], "testing 1, 2, 3" ) != 0 ) {
5037 printf( "msgrcv failed to get the correct message \n" );
5038 goto test_failed_exit
;
5041 my_err
= msgctl( my_msg_queue_id
, IPC_STAT
, &my_msq_ds
);
5042 if ( my_err
== -1 ) {
5043 printf( "msgctl failed with errno %d - %s \n", errno
, strerror( errno
) );
5044 goto test_failed_exit
;
5046 if ( my_msq_ds
.msg_qnum
!= 0 ) {
5047 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" );
5048 goto test_failed_exit
;
5051 /* tear down the message queue */
5052 my_err
= msgctl( my_msg_queue_id
, IPC_RMID
, NULL
);
5053 if ( my_err
== -1 ) {
5054 printf( "msgctl IPC_RMID failed with errno %d - %s \n", errno
, strerror( errno
) );
5055 goto test_failed_exit
;
5057 my_msg_queue_id
= -1;
5060 goto test_passed_exit
;
5066 if ( my_msg_queue_id
!= -1 ) {
5067 msgctl( my_msg_queue_id
, IPC_RMID
, NULL
);
5074 /* **************************************************************************************************************
5075 * Test execution from data and stack areas.
5076 * **************************************************************************************************************
5078 int data_exec_tests( void * the_argp
)
5082 posix_spawnattr_t attrp
;
5083 char *argv
[] = { "helpers/data_exec32nonxspawn", NULL
};
5085 int my_pid
, my_status
, ret
;
5087 if ((arch
= get_architecture()) == -1) {
5088 printf("data_exec_test: couldn't determine architecture\n");
5089 goto test_failed_exit
;
5095 * If the machine is 64-bit capable, run both the 32 and 64 bit versions of the test.
5096 * Otherwise, just run the 32-bit version.
5099 if (arch
== INTEL
) {
5101 if (system("arch -arch x86_64 helpers/data_exec") != 0) {
5102 printf("data_exec-x86_64 failed\n");
5103 goto test_failed_exit
;
5107 if (system("arch -arch i386 helpers/data_exec") != 0) {
5108 printf("data_exec-i386 failed\n");
5109 goto test_failed_exit
;
5112 posix_spawnattr_init(&attrp
);
5113 posix_spawnattr_setflags(&attrp
, _POSIX_SPAWN_ALLOW_DATA_EXEC
);
5114 ret
= posix_spawn(&my_pid
, "helpers/data_exec32nonxspawn", NULL
, &attrp
, argv
, NULL
);
5116 printf("data_exec-i386 failed in posix_spawn %s\n", strerror(errno
));
5117 goto test_failed_exit
;
5119 ret
= wait4(my_pid
, &my_status
, 0, NULL
);
5121 printf("data_exec-i386 wait4 failed with errno %d - %s\n", errno
, strerror(errno
));
5122 goto test_failed_exit
;
5124 if (WEXITSTATUS(my_status
) != 0) {
5125 printf("data_exec-i386 _POSIX_SPAWN_ALLOW_DATA_EXEC failed\n");
5126 goto test_failed_exit
;
5130 /* Add new architectures here similar to the above. */
5132 goto test_passed_exit
;
5141 /* **************************************************************************************************************
5142 * Test KASLR-related functionality
5143 * **************************************************************************************************************
5145 int kaslr_test( void * the_argp
)
5152 size
= sizeof(slide_enabled
);
5153 result
= sysctlbyname("kern.slide", &slide_enabled
, &size
, NULL
, 0);
5155 printf("sysctlbyname(\"kern.slide\") failed with errno %d\n", errno
);
5156 goto test_failed_exit
;
5159 /* Test positive case first */
5160 size
= sizeof(slide
);
5161 result
= kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR
, &slide
, &size
);
5163 /* syscall supported, slide must be non-zero if running latest xnu and KASLR is enabled */
5164 if (slide_enabled
&& (slide
== 0)) {
5165 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported slide of 0x%016llx\n", slide
);
5166 goto test_failed_exit
;
5168 if (size
!= sizeof(slide
)) {
5169 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported size of %lu\n", size
);
5170 goto test_failed_exit
;
5173 /* Only ENOTSUP is allowed. If so, assume all calls will be unsupported */
5174 if (errno
== ENOTSUP
) {
5177 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) returned unexpected errno (errno %d)\n", errno
);
5178 goto test_failed_exit
;
5182 /* Negative cases for expected failures */
5183 size
= sizeof(slide
);
5184 result
= kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR
, NULL
/* EFAULT */, &size
);
5185 if ((result
== 0) || (errno
!= EFAULT
)) {
5186 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size) returned unexpected success or errno (result %d errno %d)\n", result
, errno
);
5187 goto test_failed_exit
;
5190 size
= sizeof(slide
) + 1; /* EINVAL */
5191 result
= kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR
, NULL
, &size
);
5192 if ((result
== 0) || (errno
!= EINVAL
)) {
5193 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size+1) returned unexpected success or errno (result %d errno %d)\n", result
, errno
);
5194 goto test_failed_exit
;
5197 result
= kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR
, NULL
/* EFAULT */, NULL
/* EFAULT */);
5198 if ((result
== 0) || (errno
!= EFAULT
)) {
5199 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, NULL) returned unexpected success or errno (result %d errno %d)\n", result
, errno
);
5200 goto test_failed_exit
;
5203 size
= sizeof(slide
);
5204 result
= kas_info(KAS_INFO_MAX_SELECTOR
/* EINVAL */, &slide
, &size
);
5205 if ((result
== 0) || (errno
!= EINVAL
)) {
5206 printf("kas_info(KAS_INFO_MAX_SELECTOR, &slide, &size) returned unexpected success or errno (result %d errno %d)\n", result
, errno
);
5207 goto test_failed_exit
;
5216 typedef struct attrs
{
5217 uint32_t attrs_length
;
5218 attribute_set_t attrs_returned
;
5219 uint32_t attr_error
;
5220 attrreference_t attr_name
;
5221 fsobj_type_t attr_obj_type
;
5225 uint32_t entry_count
;
5234 int getattrlistbulk_test( void * the_argp
)
5238 struct attrlist attr_list
;
5241 int retcount
= 0, totalcount
= 0;
5247 char* target
= "/System/Library/CoreServices";
5249 memset(&attr_list
, 0, sizeof(attr_list
));
5250 attr_list
.bitmapcount
= ATTR_BIT_MAP_COUNT
;
5251 attr_list
.commonattr
= ATTR_CMN_RETURNED_ATTRS
|
5255 ATTR_FILE_TOTALSIZE
|
5256 ATTR_DIR_ENTRYCOUNT
;
5259 /*allocate a buffer for 10 items*/
5260 attr_buf_size
= 10 * (sizeof(attrs_t
) + FILENAME_MAX
);
5261 if (vm_allocate((vm_map_t
) mach_task_self(),
5262 (vm_address_t
*)&attr_buf
,
5263 attr_buf_size
, VM_FLAGS_ANYWHERE
) != KERN_SUCCESS
) {
5264 printf( "vm_allocate failed with error %d - \"%s\" \n",
5265 errno
, strerror( errno
) );
5271 dirfd
= openat (AT_FDCWD
, target
, O_RDONLY
, 0);
5273 printf("openat \"%s\" failed with error %d - \"%s\" \n",
5274 target
, errno
, strerror( errno
));
5280 retcount
= getattrlistbulk(dirfd
,
5281 &attr_list
, &attr_buf
[0],
5282 attr_buf_size
, FSOPT_PACK_INVAL_ATTRS
);
5283 if (retcount
== -1) {
5284 printf("getattrlistbulk on %s returned %d items\n",
5285 target
, totalcount
);
5286 printf("getattrlistbulk failed with error %d - \"%s\" \n",
5287 errno
, strerror( errno
));
5290 } else if (retcount
== 0) {
5291 /* No more entries in directory */
5292 printf("getattrlistbulk succeded: found %d entries in %s\n", totalcount
, target
);
5296 totalcount
+= retcount
;
5297 entry_start
= &attr_buf
[0];
5298 for (index
= 0; index
< retcount
; index
++) {
5299 /*set attrsptr to item record buffer*/
5300 attrsptr
= (attrs_t
*)entry_start
;
5303 *calculate starting point for next item in bulk
5306 entry_start
+= attrsptr
->attrs_length
;
5308 if ((attrsptr
->attrs_returned
.commonattr
& ATTR_CMN_ERROR
) &&
5309 attrsptr
->attr_error
) {
5310 nameptr
= (char*)(&(attrsptr
->attr_name
)) + attrsptr
->attr_name
.attr_dataoffset
;
5311 printf("getattrlistbulk item \"%s\" ATTR_CMN_ERROR %d \"%s\"\n",
5312 nameptr
, attrsptr
->attr_error
,
5313 strerror(attrsptr
->attr_error
));
5324 if (attr_buf
!= NULL
) {
5326 mach_task_self(), (vm_address_t
)attr_buf
, attr_buf_size
);
5332 #define INVALID_FD -173
5333 static int create_random_name_at(int the_dirfd
, char *the_dirpathp
,
5334 char *the_namep
, size_t the_namep_len
,
5335 char *the_pathp
, size_t the_pathp_len
,
5338 * create_random_name_at - creates a file with a random / unique name in the given directory.
5339 * when do_create is true we create a file else we generaate a name that does not exist in the
5340 * given directory (we do not create anything when do_open is 0).
5341 * A name is generated relative to the directory fd. If both a directory path and
5342 * and a buffer to hold the full pathname are provided, an abolute pathname is also returned.
5343 * An absolute pathname for the generated filename is returned in my_pathp.
5344 * WARNING - caller provides enough space in the_namep buffer for longest possible name (NAME_MAX).
5345 * WARNING - caller provides enough space in the_pathp buffer for longest possible path (PATH_MAX).
5346 * RAND_MAX is currently 2147483647 (ten characters plus one for a slash)
5348 int create_random_name_at(int the_dirfd
, char *the_dirpathp
,
5349 char *the_namep
, size_t the_namep_len
,
5350 char *the_pathp
, size_t the_pathp_len
,
5356 for ( i
= 0; i
< 1; i
++ ) {
5362 sprintf( &my_name
[0], "%d", my_rand
);
5363 if ( (strlen( &my_name
[0] ) + strlen( the_dirpathp
) + 2) > PATH_MAX
) {
5364 printf( "%s - path to test file greater than PATH_MAX \n", __FUNCTION__
);
5368 // generate name and absolute path
5370 *(myp
) = (char)0x00;
5371 strlcat(the_namep
, &my_name
[0], the_namep_len
);
5374 *If the caller has passed in a path pointer and directory path
5375 *it means an absolute path is to be returned as well.
5377 if (the_pathp
&& the_dirpathp
) {
5378 *the_pathp
= (char)0x00;
5379 strlcat(the_pathp
, the_dirpathp
, the_pathp_len
);
5380 strlcat(the_pathp
, "/", the_pathp_len
);
5381 strlcat(the_pathp
, the_namep
, the_pathp_len
);
5385 /* create a file with this name */
5386 my_fd
= openat( the_dirfd
, the_namep
, (O_RDWR
| O_CREAT
| O_EXCL
),
5387 (S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
) );
5388 if ( my_fd
== -1 ) {
5389 if ( errno
!= EEXIST
) {
5390 printf( "%s - open failed with errno %d - %s \n",
5391 __FUNCTION__
, errno
, strerror( errno
) );
5394 // name already exists, try another
5401 /* make sure the name is unique */
5403 my_err
= fstatat( the_dirfd
, the_namep
, &my_sb
, 0 );
5404 if ( my_err
!= 0 ) {
5405 if ( errno
== ENOENT
) {
5409 printf( "%s - open failed with errno %d - %s \n",
5410 __FUNCTION__
, errno
, strerror( errno
) );
5414 /* name already exists, try another */
5425 } /* create_random_name_at */
5427 /* **************************************************************************************************************
5428 * Test close, fpathconf, fstat, open, pathconf system calls.
5429 * **************************************************************************************************************
5431 int openat_close_test( void * the_argp
)
5437 char * my_dirpathp
= NULL
;
5438 char * my_namep
= NULL
;
5439 char * my_pathp
= NULL
;
5441 long my_pconf_result
;
5444 kern_return_t my_kr
;
5447 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_dirpathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
5448 if(my_kr
!= KERN_SUCCESS
){
5449 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5450 goto test_failed_exit
;
5453 *my_dirpathp
= 0x00;
5454 strlcat( my_dirpathp
, &g_target_path
[0], PATH_MAX
);
5456 my_dirfd
= openat(AT_FDCWD
, my_dirpathp
, O_RDONLY
, 0 );
5457 if ( my_dirfd
== -1 ) {
5458 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5459 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
5460 goto test_failed_exit
;
5463 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
5464 if(my_kr
!= KERN_SUCCESS
){
5465 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5466 goto test_failed_exit
;
5474 /* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
5475 if (*my_dirpathp
== '/') {
5476 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
5477 if(my_kr
!= KERN_SUCCESS
){
5478 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5479 goto test_failed_exit
;
5484 * Some basic openat validation. If pathname is absolute, invalid fd should
5488 if (*my_dirpathp
== '/') {
5489 my_dirfd
= openat( INVALID_FD
, my_dirpathp
, O_RDONLY
, 0 );
5490 if ( my_dirfd
== -1 ) {
5491 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5492 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
5493 printf( "\t Was Absolute pathname, invalid fd, %d, provided as input \n", INVALID_FD
);
5494 goto test_failed_exit
;
5500 my_dirfd
= openat( AT_FDCWD
, my_dirpathp
, O_RDONLY
, 0 );
5501 if ( my_dirfd
== -1 ) {
5502 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5503 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
5504 goto test_failed_exit
;
5507 /* create a test file */
5508 my_err
= create_random_name_at( my_dirfd
, my_dirpathp
, my_namep
, NAME_MAX
, my_pathp
, PATH_MAX
, 1 );
5509 if ( my_err
!= 0 ) {
5510 goto test_failed_exit
;
5514 * If pathname is not absolute, an openat relative to a invalid directory fd
5518 /* test O_WRONLY case */
5519 my_fd
= openat( INVALID_FD
, my_namep
, O_WRONLY
, 0 );
5520 if ( my_fd
!= -1 ) {
5521 printf( "openat call relative to invalid dir fd worked\n");
5522 printf( "\t file we attempted to open -> \"%s\" relative to fd -173\n", my_pathp
);
5523 goto test_failed_exit
;
5527 /* test O_WRONLY case */
5528 my_fd
= openat( my_dirfd
, my_namep
, O_WRONLY
, 0 );
5529 if ( my_fd
== -1 ) {
5530 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5531 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
5532 goto test_failed_exit
;
5536 * try to open relative to non-directory fd.
5537 * It should fail with ENOTDIR.
5539 if ((error_fd
= openat(my_fd
, my_namep
, O_WRONLY
, 0)) != -1) {
5540 printf( "openat call succeded with fd being a non-directory fd\n");
5541 printf( "\t file we attempted to open (reltive to itself)-> \"%s\" \n", my_pathp
);
5543 goto test_failed_exit
;
5544 } else if (errno
!= ENOTDIR
) {
5545 printf( "openat call should have failed with errno 20 (ENOTDIR). actually failed with %d - \"%s\" \n", my_err
, strerror( my_err
) );
5548 my_pconf_result
= fpathconf( my_fd
, _PC_NAME_MAX
);
5549 if ( my_pconf_result
== -1 ) {
5550 printf( "fpathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5551 goto test_failed_exit
;
5553 // printf( "_PC_NAME_MAX %ld \n", my_pconf_result );
5554 /* results look OK? */
5555 if ( my_pconf_result
< 6 ) {
5556 printf( "fpathconf - _PC_NAME_MAX - looks like wrong results \n" );
5557 goto test_failed_exit
;
5560 /* write some data then try to read it */
5561 my_result
= write( my_fd
, "kat", 3 );
5563 if ( my_result
!= 3 ) {
5564 if ( sizeof( ssize_t
) > sizeof( int ) ) {
5565 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
5568 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
5570 goto test_failed_exit
;
5573 /* Try to read - this should fail since we opened file with O_WRONLY */
5574 my_result
= read( my_fd
, &my_buffer
[0], sizeof(my_buffer
) );
5576 if ( my_result
!= -1 ) {
5577 printf( "read call should have failed with errno 9 (EBADF) \n" );
5578 goto test_failed_exit
;
5580 else if ( my_err
!= EBADF
) {
5581 printf( "read call should have failed with errno 9 (EBADF). actually failed with %d - \"%s\" \n", my_err
, strerror( my_err
) );
5582 goto test_failed_exit
;
5587 /* test O_TRUNC and O_APPEND case */
5588 my_fd
= openat( my_dirfd
, my_namep
, (O_RDWR
| O_TRUNC
| O_APPEND
), 0 );
5589 if ( my_fd
== -1 ) {
5590 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5591 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
5592 goto test_failed_exit
;
5595 my_result
= read( my_fd
, &my_buffer
[0], sizeof(my_buffer
) );
5596 if ( my_result
== -1 ) {
5597 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5598 goto test_failed_exit
;
5600 if ( my_result
!= 0 ) {
5601 printf( "read failed - should have read 0 bytes. \n" );
5602 goto test_failed_exit
;
5605 my_result
= write( my_fd
, "kat", 3 );
5607 if ( my_result
!= 3 ) {
5608 if ( sizeof( ssize_t
) > sizeof( int ) ) {
5609 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
5612 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
5614 goto test_failed_exit
;
5617 /* add some more data to the test file - this should be appended */
5618 lseek( my_fd
, 0, SEEK_SET
);
5619 my_result
= write( my_fd
, "zzz", 3 );
5621 if ( my_result
!= 3 ) {
5622 if ( sizeof( ssize_t
) > sizeof( int ) ) {
5623 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
5626 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
5628 goto test_failed_exit
;
5631 /* now verify the writes */
5632 bzero( (void *)&my_buffer
[0], sizeof(my_buffer
) );
5633 lseek( my_fd
, 0, SEEK_SET
);
5634 my_result
= read( my_fd
, &my_buffer
[0], sizeof(my_buffer
) );
5635 if ( my_result
== -1 ) {
5636 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5637 goto test_failed_exit
;
5639 if ( my_buffer
[0] != 'k' || my_buffer
[5] != 'z' ) {
5640 printf( "read failed to get correct data \n" );
5641 goto test_failed_exit
;
5645 * try to stat relative to non-directory fd.
5646 * It should fail with ENOTDIR.
5648 if ((fstatat( my_fd
, my_namep
, &my_sb
, 0 )) != -1) {
5649 printf( "fstatat call succeded with fd being a non-directory fd\n");
5650 printf( "\t file we attempted to stat (relative to itself)-> \"%s\" \n", my_pathp
);
5651 goto test_failed_exit
;
5652 } else if (errno
!= ENOTDIR
) {
5653 printf( "fstatat call should have failed with errno 20 (ENOTDIR). actually failed with %d - \"%s\" \n", my_err
, strerror( my_err
) );
5657 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
5658 if ( my_err
== -1 ) {
5659 printf( "fstatat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5660 goto test_failed_exit
;
5662 if ( my_sb
.st_size
!= 6 ) {
5663 printf( "fstatat call failed - st_size is wrong \n" );
5664 goto test_failed_exit
;
5666 if ( !S_ISREG( my_sb
.st_mode
) ) {
5667 printf( "fstatat call failed - st_mode does not indicate regular file \n" );
5668 goto test_failed_exit
;
5672 goto test_passed_exit
;
5681 if ( my_pathp
!= NULL
) {
5683 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
5687 unlinkat( my_dirfd
, my_pathp
, 0 );
5688 vm_deallocate(mach_task_self(), (vm_address_t
)my_namep
, NAME_MAX
);
5691 if ( my_dirfd
!= -1)
5694 if ( my_dirpathp
!= NULL
) {
5695 vm_deallocate(mach_task_self(), (vm_address_t
)my_dirpathp
, PATH_MAX
);
5701 /* **************************************************************************************************************
5702 * Test linkat, fstatat and unlinkat system calls.
5703 * **************************************************************************************************************
5705 int linkat_fstatat_unlinkat_test( void * the_argp
)
5710 char * my_dirpathp
= NULL
;
5711 char * my_namep
= NULL
;
5712 char * my_pathp
= NULL
;
5713 char * my_name2p
= NULL
;
5714 nlink_t my_link_count
;
5717 kern_return_t my_kr
;
5720 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_dirpathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
5721 if(my_kr
!= KERN_SUCCESS
){
5722 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5723 goto test_failed_exit
;
5726 *my_dirpathp
= 0x00;
5727 strlcat( my_dirpathp
, &g_target_path
[0], PATH_MAX
);
5729 my_dirfd
= openat(AT_FDCWD
, my_dirpathp
, O_RDONLY
, 0 );
5730 if ( my_dirfd
== -1 ) {
5731 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5732 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
5733 goto test_failed_exit
;
5736 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
5737 if(my_kr
!= KERN_SUCCESS
){
5738 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5739 goto test_failed_exit
;
5747 /* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
5748 if (*my_dirpathp
== '/') {
5749 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
5750 if(my_kr
!= KERN_SUCCESS
){
5751 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5752 goto test_failed_exit
;
5756 /* create a test file */
5757 my_err
= create_random_name_at( my_dirfd
, my_dirpathp
, my_namep
, NAME_MAX
, my_pathp
, PATH_MAX
, 1 );
5758 if ( my_err
!= 0 ) {
5759 goto test_failed_exit
;
5762 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_name2p
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
5763 if(my_kr
!= KERN_SUCCESS
){
5764 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5765 goto test_failed_exit
;
5770 /* now create a name for the link file */
5771 strlcat( my_name2p
, my_namep
, NAME_MAX
);
5772 strlcat( my_name2p
, "link", NAME_MAX
);
5774 /* get the current link count */
5775 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
5776 if ( my_err
!= 0 ) {
5777 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5778 goto test_failed_exit
;
5780 my_link_count
= my_sb
.st_nlink
;
5782 /* Double check with absolute path name */
5784 my_err
= fstatat(INVALID_FD
, my_pathp
, &my_sb
, 0 );
5785 if ( my_err
!= 0 ) {
5786 printf( "fstatat with INVALID_FD and absolute pathname failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5787 goto test_failed_exit
;
5789 if (my_link_count
!= my_sb
.st_nlink
) {
5790 printf( "fstatat call did not return correct number of links" );
5791 goto test_failed_exit
;
5795 /* check file size (should be 0) */
5796 if ( my_sb
.st_size
!= 0 ) {
5797 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
5798 printf( "st_size is not 0 \n" );
5799 goto test_failed_exit
;
5802 /* change file size */
5803 my_fd
= openat(my_dirfd
, my_namep
, O_RDWR
, 0 );
5804 if ( my_fd
== -1 ) {
5805 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5806 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp
);
5807 goto test_failed_exit
;
5810 my_result
= write( my_fd
, "kat", 3 );
5812 if ( my_result
!= 3 ) {
5813 if ( sizeof( ssize_t
) > sizeof( int ) ) {
5814 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result
);
5817 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result
);
5819 goto test_failed_exit
;
5824 /* now link another file to our test file and recheck link count */
5825 /* N.B. - HFS only supports AT_SYMLINK_FOLLOW */
5826 my_err
= linkat( my_dirfd
, my_namep
, my_dirfd
, my_name2p
, AT_SYMLINK_FOLLOW
);
5827 if ( my_err
!= 0 ) {
5828 printf( "linkat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5829 goto test_failed_exit
;
5831 my_err
= fstatat( my_dirfd
, my_pathp
, &my_sb
, 0 );
5832 if ( my_err
!= 0 ) {
5833 printf( "fstatat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5834 goto test_failed_exit
;
5836 if ( (my_link_count
+ 1) != my_sb
.st_nlink
) {
5837 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
5838 printf( "incorrect st_nlink \n" );
5839 goto test_failed_exit
;
5842 /* check file size (should be 3) */
5843 if ( my_sb
.st_size
!= 3 ) {
5844 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
5845 printf( "st_size is not 3 \n" );
5846 goto test_failed_exit
;
5849 /* now make sure unlink works OK */
5850 my_err
= unlinkat( my_dirfd
, my_name2p
, 0 );
5851 if ( my_err
!= 0 ) {
5852 printf( "unlinkat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5853 goto test_failed_exit
;
5855 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
5856 if ( my_err
!= 0 ) {
5857 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5858 goto test_failed_exit
;
5860 if ( my_link_count
!= my_sb
.st_nlink
) {
5861 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp
);
5862 printf( "incorrect st_nlink \n" );
5863 goto test_failed_exit
;
5867 goto test_passed_exit
;
5876 if ( my_name2p
!= NULL
) {
5877 (void)unlinkat( my_dirfd
, my_name2p
, 0 );
5878 vm_deallocate(mach_task_self(), (vm_address_t
)my_name2p
, NAME_MAX
);
5881 if ( my_namep
!= NULL
) {
5882 (void)unlinkat( my_dirfd
, my_name2p
, 0 );
5883 vm_deallocate(mach_task_self(), (vm_address_t
)my_name2p
, NAME_MAX
);
5886 if ( my_pathp
!= NULL
) {
5888 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
5891 if ( my_dirpathp
!= NULL
) {
5892 vm_deallocate(mach_task_self(), (vm_address_t
)my_dirpathp
, PATH_MAX
);
5895 if ( my_dirfd
!= -1 )
5901 /* **************************************************************************************************************
5902 * Test faccessat, fchmodat and fchmod system calls.
5903 * **************************************************************************************************************
5905 int faccessat_fchmodat_fchmod_test( void * the_argp
)
5908 int is_absolute_path
= 0;
5913 char * my_dirpathp
= NULL
;
5914 char * my_namep
= NULL
;
5915 char * my_pathp
= NULL
;
5922 kern_return_t my_kr
;
5925 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_dirpathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
5926 if(my_kr
!= KERN_SUCCESS
){
5927 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5928 goto test_failed_exit
;
5931 *my_dirpathp
= 0x00;
5932 strlcat( my_dirpathp
, &g_target_path
[0], PATH_MAX
);
5935 * Some basic openat validation. If pathname is absolute, an invalid fd should
5939 if (*my_dirpathp
== '/') {
5940 is_absolute_path
= 1;
5941 my_dirfd
= openat(INVALID_FD
, my_dirpathp
, O_RDONLY
, 0 );
5942 if ( my_dirfd
== -1 ) {
5943 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5944 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
5945 printf( "\t Was Absolute pathname, invalid fd, %d, provided as input \n", INVALID_FD
);
5946 goto test_failed_exit
;
5951 my_dirfd
= openat(AT_FDCWD
, my_dirpathp
, O_RDONLY
, 0 );
5952 if ( my_dirfd
== -1 ) {
5953 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5954 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
5955 goto test_failed_exit
;
5958 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
5959 if(my_kr
!= KERN_SUCCESS
){
5960 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5961 goto test_failed_exit
;
5966 if (is_absolute_path
) {
5967 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
5968 if(my_kr
!= KERN_SUCCESS
){
5969 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
5970 goto test_failed_exit
;
5976 /* create a test file */
5977 my_err
= create_random_name_at(my_dirfd
, my_dirpathp
, my_namep
, NAME_MAX
, my_pathp
, PATH_MAX
, 1);
5978 if ( my_err
!= 0 ) {
5979 goto test_failed_exit
;
5983 my_err
= fchmodat(my_dirfd
, my_namep
, S_IRWXU
, 0);
5984 if ( my_err
== -1 ) {
5985 printf( "chmod call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5986 goto test_failed_exit
;
5989 my_err
= fchmodat( my_dirfd
, my_namep
, (S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
), 0 );
5990 if ( my_err
== -1 ) {
5991 printf( "chmod call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
5992 goto test_failed_exit
;
5995 /* test access - this should fail */
5996 my_err
= faccessat( my_dirfd
, my_namep
, (X_OK
), 0 );
5997 if ( my_err
== 0 ) {
5998 printf( "access call should have failed, but did not. \n" );
5999 goto test_failed_exit
;
6001 else if ( my_err
== -1 ) {
6005 /* special case when running as root - we get back EPERM when running as root */
6007 if ( ( tmp
== 0 && my_err
!= EPERM
) || (tmp
!= 0 && my_err
!= EACCES
) ) {
6008 printf( "access failed with errno %d - %s. \n", my_err
, strerror( my_err
) );
6009 goto test_failed_exit
;
6013 /* verify correct modes are set */
6014 /* First check that Absolute path works even with an invalid FD */
6015 if (is_absolute_path
) {
6016 my_err
= fstatat( INVALID_FD
, my_pathp
, &my_sb
, 0 );
6017 if ( my_err
!= 0 ) {
6018 printf( "fstatat call failed with an absolute pathname. got errno %d - %s. \n", errno
, strerror( errno
) );
6019 goto test_failed_exit
;
6023 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
6024 if ( my_err
!= 0 ) {
6025 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6026 goto test_failed_exit
;
6029 if ( (my_sb
.st_mode
& (S_IRWXO
| S_IXGRP
)) != 0 ||
6030 (my_sb
.st_mode
& (S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
)) == 0 ) {
6031 printf( "chmod call appears to have failed. stat shows incorrect values in st_mode! \n" );
6032 goto test_failed_exit
;
6036 /* another test for the access system call -- refer ro radar# 6725311 */
6040 * This test makes sure that the access system call does not give the current user extra
6041 * permissions on files the current user does not own. From radar #6725311, this could
6042 * happen when the current user calls access() on a file owned by the current user in
6043 * the same directory as the other files not owned by the current user.
6045 * Note: This test expects that the effective uid (euid) is set to root.
6049 /* Create a file that root owns */
6050 file_handle
= fopen(FILE_NOTME
, "w");
6051 fclose(file_handle
);
6053 /* Currently running as root (through settid manipulation), switch to running as the current user. */
6055 my_err
= syscall(SYS_settid
, ruid
, KAUTH_GID_NONE
);
6057 printf("Failed to settid to non-root with error %d:%s\n", errno
, strerror(errno
));
6058 goto test_failed_exit
;
6061 /* Create a file that the current user owns */
6062 file_handle
= fopen(FILE_ME
, "w");
6063 fclose(file_handle
);
6067 /* Try to remove the file owned by root (this should fail). */
6068 my_err
= unlinkat( AT_FDCWD
, FILE_NOTME
, 0 );
6075 printf("Unresolved: First attempt deleted '" FILE_NOTME
"'! \n");
6078 printf("Passed: First attempt to delete '" FILE_NOTME
"' failed with error %d - %s.\n", my_err
, strerror( my_err
));
6080 /* Set _DELETE_OK on a file that the current user owns */
6081 faccessat(AT_FDCWD
, FILE_ME
, _DELETE_OK
, 0 );
6083 /* Try to remove the file owned by root again (should give us: EPERM [13]) */
6084 my_err
= unlinkat(AT_FDCWD
, FILE_NOTME
, 0);
6091 printf("Failed: Second attempt deleted '" FILE_NOTME
"'!\n");
6093 } else if (my_err
== 13) {
6094 printf("Passed: Second attempt to delete '" FILE_NOTME
"' failed with error %d - %s.\n", my_err
, strerror( my_err
));
6096 printf("Failed: Second attempt to delete '" FILE_NOTME
"' failed with error %d - %s.\n", my_err
, strerror( my_err
));
6101 /* Reset to running as root */
6102 my_err
= syscall(SYS_settid
, KAUTH_UID_NONE
, KAUTH_GID_NONE
);
6104 printf("Failed to settid revert to root with error %d:%s\n", errno
, strerror(errno
));
6105 goto test_failed_exit
;
6108 if(error_occurred
== 1) {
6109 goto test_failed_exit
;
6117 my_fd
= openat( my_dirfd
, my_namep
, O_RDONLY
, 0);
6118 if ( my_fd
== -1 ) {
6119 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6120 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path
[0] );
6121 goto test_failed_exit
;
6124 my_err
= fchmod( my_fd
, S_IRWXU
);
6125 if ( my_err
== -1 ) {
6126 printf( "fchmod call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6127 goto test_failed_exit
;
6130 my_err
= fstatat( INVALID_FD
, my_pathp
, &my_sb
, 0 );
6131 if ( my_err
!= 0 ) {
6132 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6133 goto test_failed_exit
;
6136 /* verify correct modes are set */
6137 if ( (my_sb
.st_mode
& (S_IRWXG
| S_IRWXO
)) != 0 ||
6138 (my_sb
.st_mode
& (S_IRWXU
)) == 0 ) {
6139 printf( "fchmod call appears to have failed. stat shows incorrect values in st_mode! \n" );
6140 goto test_failed_exit
;
6144 goto test_passed_exit
;
6152 if ( my_pathp
!= NULL
) {
6154 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
6156 if ( my_namep
!= NULL
) {
6157 unlinkat(my_dirfd
, my_namep
, 0);
6158 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, NAME_MAX
);
6162 if ( my_dirfd
!= -1)
6165 if ( my_dirpathp
!= NULL
) {
6166 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
6172 /* **************************************************************************************************************
6173 * Test fchownat, fchown, readlinkat, symlinkat system calls.
6174 * **************************************************************************************************************
6176 int fchownat_fchown_symlinkat_test( void * the_argp
)
6178 int my_err
, my_group_count
, i
;
6181 char * my_dirpathp
= NULL
;
6182 char * my_namep
= NULL
;
6183 char * my_link_namep
= NULL
;
6184 char * my_pathp
= NULL
;
6185 char * my_link_pathp
= NULL
;
6186 int is_absolute_path
= 0;
6188 gid_t my_orig_gid
, my_new_gid1
= 0, my_new_gid2
= 0;
6191 gid_t my_groups
[ NGROUPS_MAX
];
6192 char my_buffer
[ 64 ];
6193 kern_return_t my_kr
;
6196 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_dirpathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6197 if(my_kr
!= KERN_SUCCESS
){
6198 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6199 goto test_failed_exit
;
6202 *my_dirpathp
= 0x00;
6203 strlcat( my_dirpathp
, &g_target_path
[0], PATH_MAX
);
6206 * Some basic openat validation. If pathname is absolute, an invalid fd should
6209 if (*my_dirpathp
== '/') {
6210 is_absolute_path
= 1;
6211 my_dirfd
= openat(INVALID_FD
, my_dirpathp
, O_RDONLY
, 0 );
6212 if ( my_dirfd
== -1 ) {
6213 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6214 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
6215 printf( "\t Was Absolute pathname, invalid fd, %d, provided as input \n", INVALID_FD
);
6216 goto test_failed_exit
;
6221 my_dirfd
= openat(AT_FDCWD
, my_dirpathp
, O_RDONLY
, 0 );
6222 if ( my_dirfd
== -1 ) {
6223 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6224 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
6225 goto test_failed_exit
;
6228 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
6229 if(my_kr
!= KERN_SUCCESS
){
6230 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6231 goto test_failed_exit
;
6236 if (is_absolute_path
) {
6237 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6238 if(my_kr
!= KERN_SUCCESS
){
6239 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6240 goto test_failed_exit
;
6246 /* create a test file */
6247 my_err
= create_random_name_at(my_dirfd
, my_dirpathp
, my_namep
, NAME_MAX
, my_pathp
, PATH_MAX
, 1);
6248 if ( my_err
!= 0 ) {
6249 goto test_failed_exit
;
6252 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_link_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
6253 if(my_kr
!= KERN_SUCCESS
){
6254 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6255 goto test_failed_exit
;
6258 *my_link_namep
= 0x00;
6260 if (is_absolute_path
) {
6261 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_link_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6262 if(my_kr
!= KERN_SUCCESS
){
6263 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6264 goto test_failed_exit
;
6267 *my_link_pathp
= 0x00;
6270 /* get a name for the link (to create the symlink later) */
6271 my_err
= create_random_name_at(my_dirfd
, my_dirpathp
, my_link_namep
, NAME_MAX
, my_link_pathp
, PATH_MAX
, 0 );
6272 if ( my_err
!= 0 ) {
6273 goto test_failed_exit
;
6276 if ( !_prime_groups() ) {
6277 goto test_failed_exit
;
6280 /* set up by getting a list of groups */
6281 my_group_count
= getgroups( NGROUPS_MAX
, &my_groups
[0] );
6283 if ( my_group_count
== -1 || my_group_count
< 1 ) {
6284 printf( "getgroups call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6285 goto test_failed_exit
;
6288 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
6289 if ( my_err
!= 0 ) {
6290 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6291 goto test_failed_exit
;
6294 /* now change group owner to something other than current value */
6295 my_orig_gid
= my_sb
.st_gid
;
6296 my_orig_uid
= my_sb
.st_uid
;
6298 for ( i
= 0; i
< my_group_count
; i
++ ) {
6299 if ( my_orig_gid
!= my_groups
[ i
] ) {
6300 if ( my_new_gid1
== 0 ) {
6301 my_new_gid1
= my_groups
[ i
];
6303 else if( my_new_gid1
!= my_groups
[ i
] ) {
6304 my_new_gid2
= my_groups
[ i
];
6309 if ( i
>= my_group_count
) {
6310 printf( "not enough groups to choose from. st_gid is the same as current groups! \n" );
6311 goto test_failed_exit
;
6314 my_err
= fchownat( my_dirfd
, my_namep
, my_orig_uid
, my_new_gid1
, 0 );
6315 if ( my_err
!= 0 ) {
6316 printf( "chown call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6317 goto test_failed_exit
;
6320 /* make sure the group owner was changed */
6321 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
6322 if ( my_err
!= 0 ) {
6323 printf( "stat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6324 goto test_failed_exit
;
6326 if ( my_sb
.st_gid
== my_orig_gid
) {
6327 printf( "chown call failed. st_gid is not correct! \n" );
6328 goto test_failed_exit
;
6331 /* change group owner back using fchown */
6332 if (is_absolute_path
) {
6333 my_fd
= openat( INVALID_FD
, my_pathp
, O_RDWR
, 0 );
6335 my_fd
= openat( my_dirfd
, my_namep
, O_RDWR
, 0 );
6338 if ( my_fd
== -1 ) {
6339 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6340 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path
[0] );
6341 goto test_failed_exit
;
6344 my_err
= fchown( my_fd
, my_orig_uid
, my_new_gid2
);
6345 if ( my_err
!= 0 ) {
6346 printf( "fchown call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6347 goto test_failed_exit
;
6350 /* make sure the group owner was changed back to the original value */
6351 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
6352 if ( my_err
!= 0 ) {
6353 printf( "fstatat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6354 goto test_failed_exit
;
6356 if ( my_sb
.st_gid
== my_new_gid1
) {
6357 printf( "fchown call failed. st_gid is not correct! \n" );
6358 goto test_failed_exit
;
6361 /* create a link file and test fstatat(..., AT_SYMLINK_NOFOLLOW) */
6362 my_err
= symlinkat( my_namep
, my_dirfd
, my_link_namep
);
6363 if ( my_err
!= 0 ) {
6364 printf( "symlinkat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6365 goto test_failed_exit
;
6368 my_err
= fstatat( my_dirfd
, my_link_namep
, &my_sb
, AT_SYMLINK_NOFOLLOW
);
6369 if ( my_err
!= 0 ) {
6370 printf( "fstatat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6371 goto test_failed_exit
;
6374 /* now change group owner to something other than current value */
6375 my_orig_gid
= my_sb
.st_gid
;
6376 my_orig_uid
= my_sb
.st_uid
;
6377 my_err
= fchownat( my_dirfd
, my_link_namep
, my_orig_uid
, my_new_gid1
, AT_SYMLINK_NOFOLLOW
);
6378 if ( my_err
!= 0 ) {
6379 printf( "fchownat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6380 goto test_failed_exit
;
6383 /* make sure the group owner was changed to new value */
6384 my_err
= fstatat( my_dirfd
, my_link_namep
, &my_sb
, AT_SYMLINK_NOFOLLOW
);
6385 if ( my_err
!= 0 ) {
6386 printf( "fstatat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6387 goto test_failed_exit
;
6389 if ( my_sb
.st_gid
== my_new_gid2
) {
6390 printf( "fchownat call failed. st_gid is not correct! \n" );
6391 goto test_failed_exit
;
6394 /* make sure we can read the symlink file */
6395 my_result
= readlinkat( my_dirfd
, my_link_namep
, &my_buffer
[0], sizeof(my_buffer
) );
6396 if ( my_result
== -1 ) {
6397 printf( "readlinkat call failed. got errno %d - %s. \n", errno
, strerror( errno
) );
6398 goto test_failed_exit
;
6400 /* make sure we read some data */
6401 if ( my_result
< 1 ) {
6402 printf( "readlinkat failed to read any data. \n" );
6403 goto test_failed_exit
;
6407 goto test_passed_exit
;
6416 unlinkat( my_dirfd
, my_namep
, 0);
6417 vm_deallocate(mach_task_self(), (vm_address_t
)my_namep
, NAME_MAX
);
6419 if ( my_pathp
!= NULL
) {
6421 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
6423 if ( my_link_namep
) {
6424 unlinkat( my_dirfd
, my_link_namep
, 0);
6425 vm_deallocate(mach_task_self(), (vm_address_t
)my_link_namep
, NAME_MAX
);
6427 if ( my_link_pathp
!= NULL
) {
6428 unlink( my_link_pathp
);
6429 vm_deallocate(mach_task_self(), (vm_address_t
)my_link_pathp
, PATH_MAX
);
6431 if ( my_dirfd
!= -1 )
6434 if ( my_dirpathp
!= NULL
) {
6435 vm_deallocate(mach_task_self(), (vm_address_t
)my_dirpathp
, PATH_MAX
);
6442 /* **************************************************************************************************************
6443 * Test mkdirat, unlinkat, umask system calls.
6444 * **************************************************************************************************************
6446 int mkdirat_unlinkat_umask_test( void * the_argp
)
6452 char * my_dirpathp
= NULL
;
6453 char * my_namep
= NULL
;
6454 char * my_pathp
= NULL
;
6455 mode_t my_orig_mask
;
6457 kern_return_t my_kr
;
6459 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_dirpathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6460 if(my_kr
!= KERN_SUCCESS
){
6461 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6462 goto test_failed_exit
;
6465 *my_dirpathp
= 0x00;
6466 strlcat( my_dirpathp
, &g_target_path
[0], PATH_MAX
);
6468 my_dirfd
= openat(AT_FDCWD
, my_dirpathp
, O_RDONLY
, 0 );
6469 if ( my_dirfd
== -1 ) {
6470 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6471 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
6472 goto test_failed_exit
;
6475 /* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
6476 if (*my_dirpathp
== '/') {
6477 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6478 if(my_kr
!= KERN_SUCCESS
){
6479 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6480 goto test_failed_exit
;
6484 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
6485 if(my_kr
!= KERN_SUCCESS
){
6486 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6487 goto test_failed_exit
;
6495 /* get a random name to use with mkdirat (don't create) */
6496 my_err
= create_random_name_at( my_dirfd
, my_dirpathp
, my_namep
, NAME_MAX
, my_pathp
, PATH_MAX
, 0 );
6497 if ( my_err
!= 0 ) {
6498 goto test_failed_exit
;
6501 /* set umask to clear WX for other and group and clear X for user */
6502 my_orig_mask
= umask( (S_IXUSR
| S_IWGRP
| S_IXGRP
| S_IWOTH
| S_IXOTH
) );
6505 /* create a directory with RWX for user, group, other (which should be limited by umask) */
6506 my_err
= mkdirat( my_dirfd
, my_namep
, (S_IRWXU
| S_IRWXG
| S_IRWXO
) );
6507 if ( my_err
== -1 ) {
6508 printf( "mkdirat failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6509 goto test_failed_exit
;
6512 /* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/
6513 my_err
= fstatat( my_dirfd
, my_pathp
, &my_sb
, 0 );
6514 if ( my_err
!= 0 ) {
6515 printf( "fstat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6516 goto test_failed_exit
;
6518 if ( (my_sb
.st_mode
& (S_IXUSR
| S_IWGRP
| S_IXGRP
| S_IWOTH
| S_IXOTH
)) != 0 ) {
6519 printf( "umask did not limit modes as it should have \n" );
6520 goto test_failed_exit
;
6523 /* get rid of our test directory */
6524 my_err
= unlinkat( my_dirfd
, my_namep
, AT_REMOVEDIR
);
6525 if ( my_err
== -1 ) {
6526 printf( "unlinkat(..., AT_REMOVEDIR) failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6527 goto test_failed_exit
;
6530 goto test_passed_exit
;
6540 unlinkat( my_dirfd
, my_namep
, AT_REMOVEDIR
);
6541 vm_deallocate(mach_task_self(), (vm_address_t
)my_namep
, NAME_MAX
);
6544 if ( my_pathp
!= NULL
) {
6546 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
6549 if ( my_dirfd
!= -1 )
6552 if ( my_dirpathp
!= NULL
) {
6553 vm_deallocate(mach_task_self(), (vm_address_t
)my_dirpathp
, PATH_MAX
);
6556 if ( did_umask
!= 0 ) {
6557 umask( my_orig_mask
);
6563 /* **************************************************************************************************************
6564 * Test renameat, fstatat system calls.
6565 * **************************************************************************************************************
6567 int renameat_test( void * the_argp
)
6571 char * my_dirpathp
= NULL
;
6572 char * my_namep
= NULL
;
6573 char * my_pathp
= NULL
;
6574 char * my_new_namep
= NULL
;
6575 char * my_new_pathp
= NULL
;
6578 kern_return_t my_kr
;
6580 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_dirpathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6581 if(my_kr
!= KERN_SUCCESS
){
6582 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6583 goto test_failed_exit
;
6586 *my_dirpathp
= 0x00;
6587 strlcat( my_dirpathp
, &g_target_path
[0], PATH_MAX
);
6589 my_dirfd
= openat(AT_FDCWD
, my_dirpathp
, O_RDONLY
, 0 );
6590 if ( my_dirfd
== -1 ) {
6591 printf( "openat call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6592 printf( "\t Directory we attempted to open -> \"%s\" \n", my_dirpathp
);
6593 goto test_failed_exit
;
6596 /* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
6597 if (*my_dirpathp
== '/') {
6598 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6599 if(my_kr
!= KERN_SUCCESS
){
6600 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6601 goto test_failed_exit
;
6605 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
6606 if(my_kr
!= KERN_SUCCESS
){
6607 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6608 goto test_failed_exit
;
6616 /* create random file */
6617 my_err
= create_random_name_at( my_dirfd
, my_dirpathp
, my_namep
, NAME_MAX
, my_pathp
, PATH_MAX
, 1 );
6618 if ( my_err
!= 0 ) {
6619 goto test_failed_exit
;
6623 /* If dirpath is absolute, we can ask for an absolute path name to file back from create_random_name_at */
6624 if (*my_dirpathp
== '/') {
6625 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_new_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6626 if(my_kr
!= KERN_SUCCESS
){
6627 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6628 goto test_failed_exit
;
6632 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_new_namep
, NAME_MAX
, VM_FLAGS_ANYWHERE
);
6633 if(my_kr
!= KERN_SUCCESS
){
6634 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6635 goto test_failed_exit
;
6638 *my_new_namep
= 0x00;
6640 *my_new_pathp
= 0x00;
6643 /* create random file */
6644 my_err
= create_random_name_at( my_dirfd
, my_dirpathp
, my_new_namep
, NAME_MAX
, my_new_pathp
, PATH_MAX
, 0 );
6645 if ( my_err
!= 0 ) {
6646 goto test_failed_exit
;
6649 /* save file ID for later use */
6650 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
6651 if ( my_err
!= 0 ) {
6652 printf( "fstatat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6653 goto test_failed_exit
;
6655 my_file_id
= my_sb
.st_ino
;
6658 my_err
= renameat( my_dirfd
, my_namep
, my_dirfd
, my_new_namep
);
6659 if ( my_err
== -1 ) {
6660 printf( "rename - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6661 goto test_failed_exit
;
6664 /* make sure old name is no longer there */
6665 my_err
= fstatat( my_dirfd
, my_namep
, &my_sb
, 0 );
6666 if ( my_err
== 0 ) {
6667 printf( "renameat call failed - found old name \n" );
6668 goto test_failed_exit
;
6671 /* make sure new name is there and is correct file id */
6672 my_err
= fstatat( my_dirfd
, my_new_namep
, &my_sb
, 0 );
6673 if ( my_err
!= 0 ) {
6674 printf( "stat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6675 goto test_failed_exit
;
6677 if ( my_file_id
!= my_sb
.st_ino
) {
6678 printf( "rename failed - wrong file id \n" );
6679 goto test_failed_exit
;
6682 /* cross check with absolute path and invalid fd */
6684 my_err
= fstatat( INVALID_FD
, my_new_pathp
, &my_sb
, 0 );
6685 if ( my_err
!= 0 ) {
6686 printf( "stat - failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6687 goto test_failed_exit
;
6689 if ( my_file_id
!= my_sb
.st_ino
) {
6690 printf( "rename failed - wrong file id \n" );
6691 goto test_failed_exit
;
6696 goto test_passed_exit
;
6702 if ( my_pathp
!= NULL
) {
6704 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
6706 if ( my_new_pathp
!= NULL
) {
6707 remove( my_new_pathp
);
6708 vm_deallocate(mach_task_self(), (vm_address_t
)my_new_pathp
, PATH_MAX
);
6713 /* **************************************************************************************************************
6714 * Test task_set_exception_ports, host_set_exception_ports
6715 * **************************************************************************************************************
6717 static int __get_except_port(int which
, mach_port_t
*portp
,
6718 exception_behavior_t
*behaviorp
,
6719 thread_state_flavor_t
*flavorp
)
6721 exception_mask_t masks
[EXC_TYPES_COUNT
];
6722 mach_msg_type_number_t nmasks
= 0;
6723 exception_port_t ports
[EXC_TYPES_COUNT
];
6724 exception_behavior_t behaviors
[EXC_TYPES_COUNT
];
6725 thread_state_flavor_t flavors
[EXC_TYPES_COUNT
];
6727 *portp
= MACH_PORT_NULL
;
6731 kern_return_t kr
= KERN_FAILURE
;
6732 if (which
== 0) { /* host port */
6733 kr
= host_get_exception_ports(mach_host_self(), EXC_MASK_BAD_ACCESS
,
6734 masks
, &nmasks
, ports
, behaviors
, flavors
);
6735 } else if (which
== 1) { /* task port */
6736 kr
= task_get_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS
,
6737 masks
, &nmasks
, ports
, behaviors
, flavors
);
6738 } else if (which
== 2) { /* thread_port */
6739 kr
= thread_get_exception_ports(mach_thread_self(), EXC_MASK_BAD_ACCESS
,
6740 masks
, &nmasks
, ports
, behaviors
, flavors
);
6742 printf("ERROR: invalid 'which' in %s\n", __func__
);
6745 if (kr
!= KERN_SUCCESS
) {
6746 printf("ERROR getting %s exception port!\n", which
== 0 ? "task" : "host");
6750 *behaviorp
= behaviors
[0];
6751 *flavorp
= flavors
[0];
6756 int set_exception_ports_test( void * the_argp
)
6758 int testFlavor
= -900000;
6760 mach_port_t exception_port
;
6762 mach_port_t old_except_port
;
6763 exception_behavior_t old_behavior
;
6764 thread_state_flavor_t old_flavor
;
6767 ret
= mach_port_allocate( mach_task_self(), MACH_PORT_RIGHT_RECEIVE
, &exception_port
);
6768 if (ret
!= KERN_SUCCESS
) {
6769 printf("ERROR allocating new exception port?!\n");
6772 ret
= mach_port_insert_right( mach_task_self(), exception_port
, exception_port
, MACH_MSG_TYPE_MAKE_SEND
);
6773 if (ret
!= KERN_SUCCESS
) {
6774 printf("ERROR inserting send right into new exception port?!\n");
6775 goto test_failed_exit
;
6778 if (__get_except_port(2, &old_except_port
, &old_behavior
, &old_flavor
) < 0)
6779 goto test_failed_exit
;
6781 ret
= thread_set_exception_ports( mach_thread_self(),
6782 EXC_MASK_BAD_ACCESS
,
6784 EXCEPTION_STATE_IDENTITY
,
6787 * this test _fails_ if we successfully set the exception port
6788 * with an invalid thread flavor
6790 if (ret
== KERN_SUCCESS
) {
6791 thread_set_exception_ports( mach_thread_self(),
6792 EXC_MASK_BAD_ACCESS
,
6793 old_except_port
, old_behavior
, old_flavor
);
6794 printf("thread_set_exception_ports failed: expected !KERN_SUCCESS for flavor %d\n", testFlavor
);
6795 goto test_failed_exit
;
6799 * so far, so good: the thread_set_exception_ports call failed,
6800 * so we don't need to reset anything, but we do need to
6801 * drop our reference to the old exception port we grabbed.
6803 mach_port_deallocate( mach_task_self(), old_except_port
);
6805 if (__get_except_port(1, &old_except_port
, &old_behavior
, &old_flavor
) < 0)
6806 goto test_failed_exit
;
6808 ret
= task_set_exception_ports( mach_task_self(),
6809 EXC_MASK_BAD_ACCESS
,
6811 EXCEPTION_STATE_IDENTITY
,
6814 * this test _fails_ if we successfully set the exception port
6815 * with an invalid thread flavor
6817 if (ret
== KERN_SUCCESS
) {
6818 task_set_exception_ports( mach_task_self(),
6819 EXC_MASK_BAD_ACCESS
,
6820 old_except_port
, old_behavior
, old_flavor
);
6821 printf("task_set_exception_ports failed: expected !KERN_SUCCESS for flavor %d\n", testFlavor
);
6822 goto test_failed_exit
;
6826 * so far, so good: the task_set_exception_ports call failed,
6827 * so we don't need to reset anything, but we do need to
6828 * drop our reference to the old exception port we grabbed.
6830 mach_port_deallocate( mach_task_self(), old_except_port
);
6833 * Now try the host exception port
6835 if (__get_except_port(0, &old_except_port
, &old_behavior
, &old_flavor
) < 0)
6836 goto test_failed_exit
;
6838 ret
= host_set_exception_ports( mach_host_self(),
6839 EXC_MASK_BAD_ACCESS
,
6841 EXCEPTION_STATE_IDENTITY
,
6844 * this test _fails_ if we successfully set the exception port
6845 * with an invalid thread flavor
6847 if (ret
== KERN_SUCCESS
) {
6848 host_set_exception_ports( mach_host_self(),
6849 EXC_MASK_BAD_ACCESS
,
6850 old_except_port
, old_behavior
, old_flavor
);
6851 printf("host_set_exception_ports failed: expected !KERN_SUCCESS for flavor %d\n", testFlavor
);
6852 goto test_failed_exit
;
6855 mach_port_deallocate( mach_task_self(), exception_port
);
6856 mach_port_deallocate( mach_task_self(), old_except_port
);
6860 mach_port_deallocate( mach_task_self(), exception_port
);
6861 if (old_except_port
!= MACH_PORT_NULL
)
6862 mach_port_deallocate( mach_task_self(), old_except_port
);
6867 #if TEST_SYSTEM_CALLS
6869 /* **************************************************************************************************************
6870 * Test xxxxxxxxx system calls.
6871 * **************************************************************************************************************
6873 int sample_test( void * the_argp
)
6877 char * my_pathp
= NULL
;
6878 kern_return_t my_kr
;
6880 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
6881 if(my_kr
!= KERN_SUCCESS
){
6882 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
6883 goto test_failed_exit
;
6887 strcat( my_pathp
, &g_target_path
[0] );
6888 strcat( my_pathp
, "/" );
6890 /* create a test file */
6891 my_err
= create_random_name( my_pathp
, 1 );
6892 if ( my_err
!= 0 ) {
6893 goto test_failed_exit
;
6896 /* add your test code here... */
6900 goto test_passed_exit
;
6908 if ( my_pathp
!= NULL
) {
6910 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);