-/* **************************************************************************************************************
- * Test kevent, kqueue system calls.
- * **************************************************************************************************************
- */
-int kqueue_tests( void * the_argp )
-{
- int my_err, my_status;
- int my_kqueue = -1;
- int my_fd = -1;
- char * my_pathp = NULL;
- pid_t my_pid, my_wait_pid;
- size_t my_count;
- int my_sockets[ 2 ] = {-1, -1};
- struct kevent my_kevent;
- struct timespec my_timeout;
- char my_buffer[ 16 ];
-
- my_pathp = (char *) malloc( PATH_MAX );
- if ( my_pathp == NULL ) {
- printf( "malloc failed with error %d - \"%s\" \n", errno, strerror( errno) );
- goto test_failed_exit;
- }
- *my_pathp = 0x00;
- strcat( my_pathp, &g_target_path[0] );
- strcat( my_pathp, "/" );
-
- /* create a test file */
- my_err = create_random_name( my_pathp, 1 );
- if ( my_err != 0 ) {
- goto test_failed_exit;
- }
-
- my_fd = open( my_pathp, O_RDWR, 0 );
- if ( my_fd == -1 ) {
- printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) );
- goto test_failed_exit;
- }
-
- my_err = socketpair( AF_UNIX, SOCK_STREAM, 0, &my_sockets[0] );
- if ( my_err == -1 ) {
- printf( "socketpair failed with errno %d - %s \n", errno, strerror( errno ) );
- goto test_failed_exit;
- }
-
- /* fork here and use pipe to communicate */
- my_pid = fork( );
- if ( my_pid == -1 ) {
- printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) );
- goto test_failed_exit;
- }
- else if ( my_pid == 0 ) {
- /*
- * child process - tell parent we are ready to go.
- */
- my_count = write( my_sockets[1], "r", 1 );
- if ( my_count == -1 ) {
- printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
- exit( -1 );
- }
-
- my_count = read( my_sockets[1], &my_buffer[0], 1 );
- if ( my_count == -1 ) {
- printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
- exit( -1 );
- }
- if ( my_buffer[0] != 'g' ) {
- printf( "read call on socket failed to get \"all done\" message \n" );
- exit( -1 );
- }
-
- /* now do some work that will trigger events our parent will track */
- my_count = write( my_fd, "11111111", 8 );
- if ( my_count == -1 ) {
- printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) );
- exit( -1 );
- }
-
- my_err = unlink( my_pathp );
- if ( my_err == -1 ) {
- printf( "unlink failed with error %d - \"%s\" \n", errno, strerror( errno) );
- exit( -1 );
- }
-
- /* wait for parent to tell us to exit */
- my_count = read( my_sockets[1], &my_buffer[0], 1 );
- if ( my_count == -1 ) {
- printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
- exit( -1 );
- }
- if ( my_buffer[0] != 'e' ) {
- printf( "read call on socket failed to get \"all done\" message \n" );
- exit( -1 );
- }
- exit(0);
- }
-
- /* parent process - wait for child to spin up */
- my_count = read( my_sockets[0], &my_buffer[0], sizeof(my_buffer) );
- if ( my_count == -1 ) {
- printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) );
- goto test_failed_exit;
- }
- if ( my_buffer[0] != 'r' ) {
- printf( "read call on socket failed to get \"ready to go message\" \n" );
- goto test_failed_exit;
- }
-
- /* set up a kqueue and register for some events */
- my_kqueue = kqueue( );
- if ( my_kqueue == -1 ) {
- printf( "kqueue call failed with error %d - \"%s\" \n", errno, strerror( errno) );
- goto test_failed_exit;
- }
-
- /* look for our test file to get unlinked or written to */
- EV_SET( &my_kevent, my_fd, EVFILT_VNODE, (EV_ADD | EV_CLEAR), (NOTE_DELETE | NOTE_WRITE), 0, 0 );
-
- my_timeout.tv_sec = 0;
- my_timeout.tv_nsec = 0;
- my_err = kevent( my_kqueue, &my_kevent, 1, NULL, 0, &my_timeout);
- if ( my_err == -1 ) {
- printf( "kevent call to register events failed with error %d - \"%s\" \n", errno, strerror( errno) );
- goto test_failed_exit;
- }
-
- /* tell child to get to work */
- my_count = write( my_sockets[0], "g", 1 );
- if ( my_count == -1 ) {
- printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
- goto test_failed_exit;
- }
-
- /* go get vnode events */
- EV_SET( &my_kevent, my_fd, EVFILT_VNODE, (EV_CLEAR), 0, 0, 0 );
- my_err = kevent( my_kqueue, NULL, 0, &my_kevent, 1, NULL );
- if ( my_err == -1 ) {
- printf( "kevent call to get vnode events failed with error %d - \"%s\" \n", errno, strerror( errno) );
- goto test_failed_exit;
- }
- if ( my_err == 0 ) {
- printf( "kevent call to get vnode events did not return any when it should have \n" );
- goto test_failed_exit;
- }
- if ( (my_kevent.fflags & (NOTE_DELETE | NOTE_WRITE)) == 0 ) {
- printf( "kevent call to get vnode events did not return NOTE_DELETE or NOTE_WRITE \n" );
- printf( "fflags 0x%02X \n", my_kevent.fflags );
- goto test_failed_exit;
- }
-
- /* tell child to get to exit */
- my_count = write( my_sockets[0], "e", 1 );
- if ( my_count == -1 ) {
- printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) );
- goto test_failed_exit;
- }
-
- my_wait_pid = wait4( my_pid, &my_status, 0, NULL );
- if ( my_wait_pid == -1 ) {
- printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) );
- goto test_failed_exit;
- }
-
- /* wait4 should return our child's pid when it exits */
- if ( my_wait_pid != my_pid ) {
- printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid );
- goto test_failed_exit;
- }
-
- if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) {
- printf( "wait4 returned wrong exit status - 0x%02X \n", my_status );
- goto test_failed_exit;
- }
-
- my_err = 0;
- goto test_passed_exit;
-
-test_failed_exit:
- my_err = -1;
-
-test_passed_exit:
- if ( my_sockets[0] != -1 )
- close( my_sockets[0] );
- if ( my_sockets[1] != -1 )
- close( my_sockets[1] );
- if ( my_kqueue != -1 )
- close( my_kqueue );
- if ( my_fd != -1 )
- close( my_fd );
- if ( my_pathp != NULL ) {
- remove( my_pathp );
- free( my_pathp );
- }
- return( my_err );
-}
-
-