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