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 typedef int boolean_t;
11 #include <sys/types.h>
12 #include "tests.h"
13 #include <pthread.h>
14 #include <assert.h>
15 #include <sys/event.h> /* for kqueue tests */
16 #include <sys/sysctl.h> /* for determining hw */
17 #include <mach/mach.h>
18 #include <mach/mach_traps.h>
19 #include <AvailabilityMacros.h> /* for determination of Mac OS X version (tiger, leopard, etc.) */
20
21
22 char g_target_path[ PATH_MAX ];
23 extern int g_skip_setuid_tests;
24
25 int msg_count = 14;
26 int last_msg_seen = 0;
27 pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;
28 pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;
29
30 #define VM_MAKE_TAG(tag) ((tag) << 24)
31 #define VM_MEMORY_MACH_MSG 20
32
33 /*
34 * create_random_name - creates a file with a random / unique name in the given directory.
35 * when do_open is true we create a file else we generaate a name that does not exist in the
36 * given directory (we do not create anything when do_open is 0).
37 * WARNING - caller provides enough space in path buffer for longest possible name.
38 * WARNING - assumes caller has appended a trailing '/' on the path passed to us.
39 * RAND_MAX is currently 2147483647 (ten characters plus one for a slash)
40 */
create_random_name(char * the_pathp,int do_open)41 int create_random_name( char *the_pathp, int do_open ) {
42 int i, my_err;
43 int my_fd = -1;
44
45 for ( i = 0; i < 1; i++ ) {
46 int my_rand;
47 char *myp;
48 char my_name[32];
49
50 my_rand = rand( );
51 sprintf( &my_name[0], "%d", my_rand );
52 if ( (strlen( &my_name[0] ) + strlen( the_pathp ) + 2) > PATH_MAX ) {
53 printf( "%s - path to test file greater than PATH_MAX \n", __FUNCTION__ );
54 return( -1 );
55 }
56
57 // append generated file name onto our path
58 myp = strrchr( the_pathp, '/' );
59 *(myp + 1) = 0x00;
60 strcat( the_pathp, &my_name[0] );
61 if ( do_open ) {
62 /* create a file with this name */
63 my_fd = open( the_pathp, (O_RDWR | O_CREAT | O_EXCL),
64 (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) );
65 if ( my_fd == -1 ) {
66 if ( errno != EEXIST ) {
67 printf( "%s - open failed with errno %d - %s \n",
68 __FUNCTION__, errno, strerror( errno ) );
69 return( -1 );
70 }
71 // name already exists, try another
72 i--;
73 continue;
74 }
75 }
76 else {
77 /* make sure the name is unique */
78 struct stat my_sb;
79 my_err = stat( the_pathp, &my_sb );
80 if ( my_err != 0 ) {
81 if ( errno == ENOENT ) {
82 break;
83 }
84 else {
85 printf( "%s - open failed with errno %d - %s \n",
86 __FUNCTION__, errno, strerror( errno ) );
87 return( -1 );
88 }
89 }
90 /* name already exists, try another */
91 i--;
92 continue;
93 }
94 }
95
96 if ( my_fd != -1 )
97 close( my_fd );
98
99 return( 0 );
100
101 } /* create_random_name */
102
103 static kern_return_t
kmsg_send(mach_port_t remote_port,int index)104 kmsg_send(mach_port_t remote_port, int index)
105 {
106 int msgh_id = 1000 + index;
107 kern_return_t my_kr;
108 mach_msg_header_t * my_kmsg = NULL;
109 mach_msg_size_t size = sizeof(mach_msg_header_t) + sizeof(int)*index;
110
111 my_kr = mach_vm_allocate( mach_task_self(),
112 (vm_address_t *)&my_kmsg,
113 size,
114 VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | TRUE );
115 if (my_kr != KERN_SUCCESS)
116 return my_kr;
117 my_kmsg->msgh_bits =
118 MACH_MSGH_BITS_SET(MACH_MSG_TYPE_COPY_SEND, 0, 0, 0);
119 my_kmsg->msgh_size = size;
120 my_kmsg->msgh_remote_port = remote_port;
121 my_kmsg->msgh_local_port = MACH_PORT_NULL;
122 my_kmsg->msgh_voucher_port = MACH_PORT_NULL;
123 my_kmsg->msgh_id = msgh_id;
124 my_kr = mach_msg( my_kmsg,
125 MACH_SEND_MSG | MACH_MSG_OPTION_NONE,
126 size,
127 0, /* receive size */
128 MACH_PORT_NULL,
129 MACH_MSG_TIMEOUT_NONE,
130 MACH_PORT_NULL );
131 mach_vm_deallocate( mach_task_self(), (vm_address_t)my_kmsg, size );
132 return my_kr;
133 }
134
135 static kern_return_t
kmsg_recv(mach_port_t portset,mach_port_t port,int * msgh_id_return)136 kmsg_recv(mach_port_t portset, mach_port_t port, int * msgh_id_return)
137 {
138 kern_return_t my_kr;
139 mach_msg_header_t * my_kmsg = NULL;
140
141 my_kr = mach_vm_allocate( mach_task_self(),
142 (vm_address_t *)&my_kmsg,
143 PAGE_SIZE,
144 VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | TRUE );
145 if (my_kr != KERN_SUCCESS)
146 return my_kr;
147 my_kr = mach_msg( my_kmsg,
148 MACH_RCV_MSG | MACH_MSG_OPTION_NONE,
149 0, /* send size */
150 PAGE_SIZE, /* receive size */
151 port,
152 MACH_MSG_TIMEOUT_NONE,
153 MACH_PORT_NULL );
154 if ( my_kr == KERN_SUCCESS &&
155 msgh_id_return != NULL )
156 *msgh_id_return = my_kmsg->msgh_id;
157 mach_vm_deallocate( mach_task_self(), (vm_address_t)my_kmsg, PAGE_SIZE );
158 return my_kr;
159 }
160
161 static void *
kmsg_consumer_thread(void * arg)162 kmsg_consumer_thread(void * arg)
163 {
164 int my_kqueue = *(int *)arg;
165 int my_err;
166 kern_return_t my_kr;
167 struct kevent my_keventv[3];
168 int msgid;
169
170 EV_SET( &my_keventv[0], 0, 0, 0, 0, 0, 0 );
171 while ( !(my_keventv[0].filter == EVFILT_USER &&
172 my_keventv[0].ident == 0)) {
173 /* keep getting events */
174 my_err = kevent( my_kqueue, NULL, 0, my_keventv, 1, NULL );
175 if ( my_err == -1 ) {
176 printf( "kevent call from consumer thread failed with error %d - \"%s\" \n", errno, strerror( errno) );
177 return (void *)-1;
178 }
179 if ( my_err == 0 ) {
180 printf( "kevent call from consumer thread did not return any events when it should have \n" );
181 return (void *)-1;
182 }
183 if ( my_keventv[0].filter == EVFILT_MACHPORT ) {
184 if ( my_keventv[0].data == 0 ) {
185 printf( "kevent call to get machport event returned 0 msg_size \n" );
186 return (void *)-1;
187 }
188 my_kr = kmsg_recv( my_keventv[0].ident, my_keventv[0].data, &msgid );
189 if ( my_kr != KERN_SUCCESS ) {
190 printf( "kmsg_recv failed with error %d - %s \n", my_kr, mach_error_string(my_kr) );
191 return (void *)-1;
192 }
193 my_keventv[0].flags = EV_ENABLE;
194 my_err = kevent( my_kqueue, my_keventv, 1, NULL, 0, NULL );
195 if ( my_err == -1 ) {
196 printf( "kevent call to re-enable machport events failed with error %d - \"%s\" \n", errno, strerror( errno) );
197 return (void *)-1;
198 }
199 if (msgid == 1000 + msg_count) {
200 pthread_mutex_lock(&my_mutex);
201 last_msg_seen = 1;
202 pthread_cond_signal(&my_cond);
203 pthread_mutex_unlock(&my_mutex);
204 }
205 }
206 }
207 return (void *)0;
208 }
209
210
211
212 /* **************************************************************************************************************
213 * Test kevent, kqueue system calls.
214 * **************************************************************************************************************
215 */
kqueue_tests(void * the_argp)216 int kqueue_tests( void * the_argp )
217 {
218 int my_err, my_status;
219 void *my_pthread_join_status;
220 int my_kqueue = -1;
221 int my_kqueue64 = -1;
222 int my_fd = -1;
223 char * my_pathp = NULL;
224 pid_t my_pid, my_wait_pid;
225 size_t my_count, my_index;
226 int my_sockets[ 2 ] = {-1, -1};
227 struct kevent my_keventv[3];
228 struct kevent64_s my_kevent64;
229 struct timespec my_timeout;
230 char my_buffer[ 16 ];
231 kern_return_t kr;
232
233 kr = mach_vm_allocate((mach_vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE);
234 if(kr != KERN_SUCCESS){
235 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) );
236 goto test_failed_exit;
237 }
238
239 *my_pathp = 0x00;
240 strcat( my_pathp, &g_target_path[0] );
241 strcat( my_pathp, "/" );
242
243 /* create a test file */
244 my_err = create_random_name( my_pathp, 1 );
245 if ( my_err != 0 ) {
246 goto test_failed_exit;
247 }
248
249 my_fd = open( my_pathp, O_RDWR, 0 );
250 if ( my_fd == -1 ) {
251 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
252 goto test_failed_exit;
253 }
254
255 my_err = socketpair( AF_UNIX, SOCK_STREAM, 0, &my_sockets[0] );
256 if ( my_err == -1 ) {
257 printf( "socketpair failed with errno %d - %s \n", errno, strerror( errno ) );
258 goto test_failed_exit;
259 }
260
261 /* fork here and use pipe to communicate */
262 my_pid = fork( );
263 if ( my_pid == -1 ) {
264 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
265 goto test_failed_exit;
266 }
267 else if ( my_pid == 0 ) {
268 /*
269 * child process - tell parent we are ready to go.
270 */
271 my_count = write( my_sockets[1], "r", 1 );
272 if ( my_count == -1 ) {
273 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
274 exit( -1 );
275 }
276
277 my_count = read( my_sockets[1], &my_buffer[0], 1 );
278 if ( my_count == -1 ) {
279 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
280 exit( -1 );
281 }
282 if ( my_buffer[0] != 'g' ) {
283 printf( "read call on socket failed to get \"all done\" message \n" );
284 exit( -1 );
285 }
286
287 /* now do some work that will trigger events our parent will track */
288 my_count = write( my_fd, "11111111", 8 );
289 if ( my_count == -1 ) {
290 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
291 exit( -1 );
292 }
293
294 my_err = unlink( my_pathp );
295 if ( my_err == -1 ) {
296 printf( "unlink failed with error %d - \"%s\" \n", errno, strerror( errno) );
297 exit( -1 );
298 }
299
300 /* wait for parent to tell us to exit */
301 my_count = read( my_sockets[1], &my_buffer[0], 1 );
302 if ( my_count == -1 ) {
303 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
304 exit( -1 );
305 }
306 if ( my_buffer[0] != 'e' ) {
307 printf( "read call on socket failed to get \"all done\" message \n" );
308 exit( -1 );
309 }
310 exit(0);
311 }
312
313 /* parent process - wait for child to spin up */
314 my_count = read( my_sockets[0], &my_buffer[0], sizeof(my_buffer) );
315 if ( my_count == -1 ) {
316 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
317 goto test_failed_exit;
318 }
319 if ( my_buffer[0] != 'r' ) {
320 printf( "read call on socket failed to get \"ready to go message\" \n" );
321 goto test_failed_exit;
322 }
323
324 /* set up a kqueue and register for some events */
325 my_kqueue = kqueue( );
326 if ( my_kqueue == -1 ) {
327 printf( "kqueue call failed with error %d - \"%s\" \n", errno, strerror( errno) );
328 goto test_failed_exit;
329 }
330
331 /* look for our test file to get unlinked or written to */
332 EV_SET( &my_keventv[0], my_fd, EVFILT_VNODE, (EV_ADD | EV_CLEAR), (NOTE_DELETE | NOTE_WRITE), 0, 0 );
333 /* also keep an eye on our child process while we're at it */
334 EV_SET( &my_keventv[1], my_pid, EVFILT_PROC, (EV_ADD | EV_ONESHOT), NOTE_EXIT, 0, 0 );
335
336 my_timeout.tv_sec = 0;
337 my_timeout.tv_nsec = 0;
338 my_err = kevent( my_kqueue, my_keventv, 2, NULL, 0, &my_timeout);
339 if ( my_err == -1 ) {
340 printf( "kevent call to register events failed with error %d - \"%s\" \n", errno, strerror( errno) );
341 goto test_failed_exit;
342 }
343
344 /* use kevent64 to test EVFILT_PROC */
345 EV_SET64( &my_kevent64, my_pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0, 0, 0 );
346 my_err = kevent64( my_kqueue, &my_kevent64, 1, NULL, 0, 0, 0);
347 if ( my_err != -1 && errno != EINVAL ) {
348 printf( "kevent64 call should fail with kqueue used for kevent() - %d\n", my_err);
349 /* goto test_failed_exit; */
350 }
351
352 my_kqueue64 = kqueue();
353 EV_SET64( &my_kevent64, my_pid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0, 0, 0 );
354 my_err = kevent64( my_kqueue64, &my_kevent64, 1, NULL, 0, 0, 0);
355 if ( my_err == -1 ) {
356 printf( "kevent64 call to get proc exit failed with error %d - \"%s\" \n", errno, strerror( errno) );
357 goto test_failed_exit;
358 }
359
360 /* tell child to get to work */
361 my_count = write( my_sockets[0], "g", 1 );
362 if ( my_count == -1 ) {
363 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
364 goto test_failed_exit;
365 }
366
367 /* go get vnode events */
368 EV_SET( &my_keventv[0], my_fd, EVFILT_VNODE, (EV_CLEAR), 0, 0, 0 );
369 my_err = kevent( my_kqueue, NULL, 0, my_keventv, 1, NULL );
370 if ( my_err == -1 ) {
371 printf( "kevent call to get vnode events failed with error %d - \"%s\" \n", errno, strerror( errno) );
372 goto test_failed_exit;
373 }
374 if ( my_err == 0 ) {
375 printf( "kevent call to get vnode events did not return any when it should have \n" );
376 goto test_failed_exit;
377 }
378 if ( (my_keventv[0].fflags & (NOTE_DELETE | NOTE_WRITE)) == 0 ) {
379 printf( "kevent call to get vnode events did not return NOTE_DELETE or NOTE_WRITE \n" );
380 printf( "fflags 0x%02X \n", my_keventv[0].fflags );
381 goto test_failed_exit;
382 }
383
384 /* tell child to exit */
385 my_count = write( my_sockets[0], "e", 1 );
386 if ( my_count == -1 ) {
387 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
388 goto test_failed_exit;
389 }
390
391 /* look for child exit notification after unregistering for vnode events */
392 EV_SET( &my_keventv[0], my_fd, EVFILT_VNODE, EV_DELETE, 0, 0, 0 );
393 my_err = kevent( my_kqueue, my_keventv, 1, my_keventv, 1, NULL );
394 if ( my_err == -1 ) {
395 printf( "kevent call to get proc exit event failed with error %d - \"%s\" \n", errno, strerror( errno) );
396 goto test_failed_exit;
397 }
398 if ( my_err == 0 ) {
399 printf( "kevent call to get proc exit event did not return any when it should have \n" );
400 goto test_failed_exit;
401 }
402 if ( my_keventv[0].filter != EVFILT_PROC ) {
403 printf( "kevent call to get proc exit event did not return EVFILT_PROC \n" );
404 printf( "filter %i \n", my_keventv[0].filter );
405 goto test_failed_exit;
406 }
407 if ( (my_keventv[0].fflags & NOTE_EXIT) == 0 ) {
408 printf( "kevent call to get proc exit event did not return NOTE_EXIT \n" );
409 printf( "fflags 0x%02X \n", my_keventv[0].fflags );
410 goto test_failed_exit;
411 }
412
413 /* look for child exit notification on the kevent64 kqueue */
414 EV_SET64( &my_kevent64, my_pid, EVFILT_PROC, EV_CLEAR, NOTE_EXIT, 0, 0, 0, 0 );
415 my_err = kevent64( my_kqueue64, NULL, 0, &my_kevent64, 1, 0, 0);
416 if ( my_err == -1 ) {
417 printf( "kevent64 call to get child exit failed with error %d - \"%s\" \n", errno, strerror( errno) );
418 goto test_failed_exit;
419 }
420 if ( my_err == 0 ) {
421 printf( "kevent64 call to get proc exit event did not return any when it should have \n" );
422 goto test_failed_exit;
423 }
424 if ( my_kevent64.filter != EVFILT_PROC ) {
425 printf( "kevent64 call to get proc exit event did not return EVFILT_PROC \n" );
426 printf( "filter %i \n", my_kevent64.filter );
427 goto test_failed_exit;
428 }
429 if ( (my_kevent64.fflags & NOTE_EXIT) == 0 ) {
430 printf( "kevent64 call to get proc exit event did not return NOTE_EXIT \n" );
431 printf( "fflags 0x%02X \n", my_kevent64.fflags );
432 goto test_failed_exit;
433 }
434
435 my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
436 if ( my_wait_pid == -1 ) {
437 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
438 goto test_failed_exit;
439 }
440
441 /* wait4 should return our child's pid when it exits */
442 if ( my_wait_pid != my_pid ) {
443 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
444 goto test_failed_exit;
445 }
446
447 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
448 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
449 goto test_failed_exit;
450 }
451
452 /* now try out EVFILT_MACHPORT and EVFILT_USER */
453 mach_port_t my_pset = MACH_PORT_NULL;
454 mach_port_t my_port = MACH_PORT_NULL;
455 kern_return_t my_kr;
456
457 my_kr = mach_port_allocate( mach_task_self(), MACH_PORT_RIGHT_PORT_SET, &my_pset );
458 if ( my_kr != KERN_SUCCESS ) {
459 printf( "mach_port_allocate failed with error %d - %s \n", my_kr, mach_error_string(my_kr) );
460 goto test_failed_exit;
461 }
462
463 my_kr = mach_port_allocate( mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &my_port );
464 if ( my_kr != KERN_SUCCESS ) {
465 printf( "mach_port_allocate failed with error %d - %s \n", my_kr, mach_error_string(my_kr) );
466 goto test_failed_exit;
467 }
468
469 /* try to register for events on my_port directly -- this should fail */
470 EV_SET( &my_keventv[0], my_port, EVFILT_MACHPORT, (EV_ADD | EV_DISPATCH), 0, 0, 0 );
471 my_err = kevent( my_kqueue, my_keventv, 1, NULL, 0, NULL );
472 if ( my_err != -1 || (errno != ENOTCAPABLE && errno != ENOTSUP) ) {
473 printf( "kevent call to register my_port should have failed, but got %s \n", strerror(errno) );
474 goto test_failed_exit;
475 }
476
477 /* now register for events on my_pset and user 0 */
478 EV_SET( &my_keventv[0], my_pset, EVFILT_MACHPORT, (EV_ADD | EV_CLEAR | EV_DISPATCH), 0, 0, 0 );
479 EV_SET( &my_keventv[1], 0, EVFILT_USER, EV_ADD, 0, 0, 0 );
480 my_err = kevent( my_kqueue, my_keventv, 2, NULL, 0, NULL );
481 if ( my_err == -1 ) {
482 printf( "kevent call to register my_pset and user 0 failed with error %d - %s \n", errno, strerror( errno) );
483 goto test_failed_exit;
484 }
485
486 pthread_t my_threadv[3];
487
488 for (my_index = 0;
489 my_index < 3;
490 my_index++) {
491 my_err = pthread_create( &my_threadv[my_index], NULL, kmsg_consumer_thread, (void *)&my_kqueue );
492 if ( my_err != 0 ) {
493 printf( "pthread_create failed with error %d - %s \n", my_err, strerror(my_err) );
494 goto test_failed_exit;
495 }
496 }
497
498 /* insert my_port into my_pset */
499 my_kr = mach_port_insert_member( mach_task_self(), my_port, my_pset );
500 if ( my_kr != KERN_SUCCESS ) {
501 printf( "mach_port_insert_member failed with error %d - %s \n", my_kr, mach_error_string(my_kr) );
502 goto test_failed_exit;
503 }
504
505 my_kr = mach_port_insert_right( mach_task_self(), my_port, my_port, MACH_MSG_TYPE_MAKE_SEND );
506 if ( my_kr != KERN_SUCCESS ) {
507 printf( "mach_port_insert_right failed with error %d - %s \n", my_kr, mach_error_string(my_kr) );
508 goto test_failed_exit;
509 }
510
511 /* send some Mach messages */
512 for (my_index = 1;
513 my_index <= msg_count;
514 my_index++) {
515 my_kr = kmsg_send( my_port, my_index );
516 if ( my_kr != KERN_SUCCESS ) {
517 printf( "kmsg_send failed with error %d - %s \n", my_kr, mach_error_string(my_kr) );
518 goto test_failed_exit;
519 }
520 }
521
522 /* make sure the last message eventually gets processed */
523 pthread_mutex_lock(&my_mutex);
524 while (last_msg_seen == 0)
525 pthread_cond_wait(&my_cond, &my_mutex);
526 pthread_mutex_unlock(&my_mutex);
527
528 /* trigger the user 0 event, telling consumer threads to exit */
529 EV_SET( &my_keventv[0], 0, EVFILT_USER, 0, NOTE_TRIGGER, 0, 0 );
530 my_err = kevent( my_kqueue, my_keventv, 1, NULL, 0, NULL );
531 if ( my_err == -1 ) {
532 printf( "kevent call to trigger user 0 failed with error %d - %s \n", errno, strerror( errno) );
533 goto test_failed_exit;
534 }
535
536 for (my_index = 0;
537 my_index < 3;
538 my_index++) {
539 my_err = pthread_join( my_threadv[my_index], &my_pthread_join_status );
540 if ( my_err != 0 ) {
541 printf( "pthread_join failed with error %d - %s \n", my_err, strerror(my_err) );
542 goto test_failed_exit;
543 }
544 if ( my_pthread_join_status != 0 ) {
545 goto test_failed_exit;
546 }
547 }
548
549 /* clear the user 0 event */
550 EV_SET( &my_keventv[0], 0, EVFILT_USER, EV_CLEAR, 0, 0, 0 );
551 my_err = kevent( my_kqueue, my_keventv, 1, NULL, 0, NULL );
552 if ( my_err == -1 ) {
553 printf( "kevent call to trigger user 0 failed with error %d - %s \n", errno, strerror( errno) );
554 goto test_failed_exit;
555 }
556
557 /* delibrately destroy my_pset while it's still registered for events */
558 my_kr = mach_port_mod_refs( mach_task_self(), my_pset, MACH_PORT_RIGHT_PORT_SET, -1 );
559 if ( my_kr != KERN_SUCCESS ) {
560 printf( "mach_port_mod_refs failed with error %d - %s \n", my_kr, mach_error_string(my_kr) );
561 goto test_failed_exit;
562 }
563
564 /* look for the event to trigger with a zero msg_size */
565 my_err = kevent( my_kqueue, NULL, 0, my_keventv, 1, NULL );
566 if ( my_err == -1 ) {
567 printf( "kevent call to get machport event failed with error %d - \"%s\" \n", errno, strerror( errno) );
568 goto test_failed_exit;
569 }
570 if ( my_err == 0 ) {
571 printf( "kevent call to get machport event did not return any when it should have \n" );
572 goto test_failed_exit;
573 }
574 if ( my_keventv[0].filter != EVFILT_MACHPORT ) {
575 printf( "kevent call to get machport event did not return EVFILT_MACHPORT \n" );
576 printf( "filter %i \n", my_keventv[0].filter );
577 goto test_failed_exit;
578 }
579 if ( my_keventv[0].data != 0 ) {
580 printf( "kevent call to get machport event did not return 0 msg_size \n" );
581 printf( "data %ld \n", (long int) my_keventv[0].data );
582 goto test_failed_exit;
583 }
584
585 my_err = 0;
586 goto test_passed_exit;
587
588 test_failed_exit:
589 my_err = -1;
590
591 test_passed_exit:
592 if ( my_sockets[0] != -1 )
593 close( my_sockets[0] );
594 if ( my_sockets[1] != -1 )
595 close( my_sockets[1] );
596 if ( my_kqueue != -1 )
597 close( my_kqueue );
598 if ( my_kqueue64 != -1 )
599 close( my_kqueue );
600 if ( my_fd != -1 )
601 close( my_fd );
602 if ( my_pathp != NULL ) {
603 remove( my_pathp );
604 mach_vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX);
605 }
606 return( my_err );
607 }
608
609
610 int
main(int argc,char * argv[])611 main(int argc, char *argv[]) {
612
613 return (kqueue_tests(NULL));
614 }
615
616