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