/*--------------------------------------------------------------------------*/ /* Copyright (c) CIMlogic Pty Ltd 1998 */ /* */ /* A.C.N. 007 012 526 */ /* */ /* All Rights Reserved */ /*--------------------------------------------------------------------------*/ /* Program: thblock */ /*--------------------------------------------------------------------------*/ /* Description: */ /* */ /* This program is a test harness for blocking and non-blocking functions */ /* in the libc library. */ /*--------------------------------------------------------------------------*/ /* Update history: */ /* Version Date By Comments */ /* */ /* 1.1 10-Jun-98 John Birrell Initial revision */ /*--------------------------------------------------------------------------*/ /* Include files: */ /*--------------------------------------------------------------------------*/ /*#include "c_defn.h" */ /* C language definitions. */ #include #include #include #include /*--------------------------------------------------------------------------*/ /* Standard C header files: */ /*--------------------------------------------------------------------------*/ #include /* Error definitions */ #include /* File control definitions. */ /*--------------------------------------------------------------------------*/ /* Global variables: */ /*--------------------------------------------------------------------------*/ int phase = 0; /* Test phase. */ /* 1 => Expect read to return */ /* before a signal. */ /* 2 => Expect read to block and */ /* the alarm signal to */ /* interrupt it. */ int sig_count = 0; /* Alarm signal count. */ /*--------------------------------------------------------------------------*/ /* Local definitions: */ /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ /* RCS identification: */ /*--------------------------------------------------------------------------*/ /* @(#) $Source: /u/src/opsys/libc/tprg/thblock.c,v $ $Date: 1998/06/10 08:18:04 $ $Revision: 1.3 $ */ /*--------------------------------------------------------------------------*/ /* Function definition: */ /*--------------------------------------------------------------------------*/ void sigalrm_handler /* Returns nothing. */ ( /*----------------------------------------------------------------------*/ /* Calling parameters: */ /*----------------------------------------------------------------------*/ int signum /* Signal number. */ ) /*--------------------------------------------------------------------------*/ /* Code: */ /*--------------------------------------------------------------------------*/ { /*----------------------------------------------------------------------*/ /* Increment the alarm signal count: */ /*----------------------------------------------------------------------*/ sig_count++; printf("Got alarm signal.\n"); } /*--------------------------------------------------------------------------*/ /* Function definition: */ /*--------------------------------------------------------------------------*/ int main ( /*----------------------------------------------------------------------*/ /* Calling parameters: */ /*----------------------------------------------------------------------*/ int argc, /* Number of arguments */ char *argv[] /* Array of pointers to arguments */ ) /*--------------------------------------------------------------------------*/ /* Code: */ /*--------------------------------------------------------------------------*/ { /*----------------------------------------------------------------------*/ /* Local variables: */ /*----------------------------------------------------------------------*/ char bufr[1024]; /* Input buffer. */ int ierr = 0; /* Error variable. */ ssize_t num; /* Number of bytes read. */ struct sigaction act; /*----------------------------------------------------------------------*/ /* Display a startup message: */ /*----------------------------------------------------------------------*/ printf("thblock: Lock test harness starting...\n"); /*----------------------------------------------------------------------*/ /* Install a signal handler to trap the alarms: */ /*----------------------------------------------------------------------*/ sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGALRM); act.sa_flags = 0; act.sa_handler = sigalrm_handler; /*if (signal(SIGALRM, sigalrm_handler) == SIG_ERR) */ if (sigaction(SIGALRM, &act, NULL) != 0) { /*------------------------------------------------------------------*/ /* Error installing signal handler: */ /*------------------------------------------------------------------*/ printf("Error %d setting signal handler\n",errno); ierr = -1; } /*----------------------------------------------------------------------*/ /* Set the standard input to non-blocking: */ /*----------------------------------------------------------------------*/ else if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) != 0) { /*------------------------------------------------------------------*/ /* Error setting flags: */ /*------------------------------------------------------------------*/ printf("Error %d setting standard input to non-blocking\n",errno); ierr = -1; } else printf("Set stdin to nonblocking.\n"); { /*------------------------------------------------------------------*/ /* Start the alarm timer: */ /*------------------------------------------------------------------*/ alarm(2); printf("Set alarm.\n"); /*------------------------------------------------------------------*/ /* Read from the non-blocking standard input: */ /*------------------------------------------------------------------*/ if ((num = read(STDIN_FILENO, bufr, sizeof(bufr))) != -1 || errno != EAGAIN) { /*--------------------------------------------------------------*/ /* Unexpected return value: */ /*--------------------------------------------------------------*/ printf("Expected a non-blocking read to return -1 (%ld) and set errno to EAGAIN (%d)\n",(long) num,errno); ierr = -1; } /*------------------------------------------------------------------*/ /* Check that an alarm signal was not received: */ /*------------------------------------------------------------------*/ else if (sig_count != 0) { /*--------------------------------------------------------------*/ /* Unexpected alarm signal: */ /*--------------------------------------------------------------*/ printf("Received %d alarm signal%s when expecting none!\n",sig_count,(sig_count > 1) ? "s":""); ierr = -1; } /*------------------------------------------------------------------*/ /* Set the standard input to blocking: */ /*------------------------------------------------------------------*/ else if (fcntl(STDIN_FILENO, F_SETFL, 0) != 0) { /*--------------------------------------------------------------*/ /* Error setting flags: */ /*--------------------------------------------------------------*/ printf("Error %d setting standard input to blocking\n",errno); ierr = -1; } /*------------------------------------------------------------------*/ /* Read from the blocking standard input and expect the read to be */ /* interrupted by a signal: */ /*------------------------------------------------------------------*/ else if ((num = read(STDIN_FILENO, bufr, sizeof(bufr))) != -1 || errno != EINTR) { /*--------------------------------------------------------------*/ /* Unexpected return value: */ /*--------------------------------------------------------------*/ printf("Expected a blocking read to return -1 (%ld) and set errno to EINTR (%d)\n",(long) num,errno); ierr = -1; } /*------------------------------------------------------------------*/ /* Check that one alarm signal was received: */ /*------------------------------------------------------------------*/ else if (sig_count != 1) { /*--------------------------------------------------------------*/ /* Unexpected alarm signal: */ /*--------------------------------------------------------------*/ printf("Received %d alarm signals when expecting one!\n",sig_count); ierr = -1; } } /*----------------------------------------------------------------------*/ /* Check for no errors: */ /*----------------------------------------------------------------------*/ if (ierr == 0) { /*------------------------------------------------------------------*/ /* Display a completion message: */ /*------------------------------------------------------------------*/ printf("Test harness completed successully\n"); } /*----------------------------------------------------------------------*/ /* Return the error status: */ /*----------------------------------------------------------------------*/ return(ierr); }