/***************************************/
/* Physics 673 - Assignment #9         */ 
/* Due: November 27, 1996              */ 
/* Signals: Part 1                     */
/* Catch a terminal-generated signal   */
/* Philip Kayal                        */
/***************************************/

/**************************************************************/
/* The terminal-generated signal will be in the form of       */
/* a CTRL C that the user must type. This will induce the     */             
/* signal SIGINT.                                             */ 
/**************************************************************/

/* Filename: pro.c */

/* Include the following C libraries: */
#include 
#include 
#include 
#include 
#include 
#include 

main()
{

/* Variable declaration */
  int k;

/* Declaration of signal-handling function. */
  void sig1func();

/* Initialization */
  k = 0;

  printf ("\nProgram started OK \n");
  fflush(stdout);

/* If the signal SIGINT occurs, then do the function sig1func  */  
  if (signal(SIGINT, sig1func) == SIG_ERR) {
    printf ("\nSignal error\n");
  }

/* Have process hang around so that the user   */
/* can type CTRL C                             */

  while (k < 1) {
    printf ("\nWaiting for user to hit CTRL C\n");
    fflush(stdout);
    sleep(5);
  }

/* Program will never finish beacuse it is terminated by the */
/* signal-handling function */
  printf ("\nProgram finished OK \n");
  fflush(stdout);
  
  return;
}

void sig1func()
{
  int k;

  printf("\nSIGINT signal caught,");
  fflush(stdout);
  printf("\ndue to user typing CTRL C.");
  fflush(stdout);
  printf("\nExiting now.\n");
  fflush(stdout);
  exit(1);
}
/***************************************/
/* Physics 673 - Assignment #9         */
/* Due: November 27, 1996              */
/* Signals: Part 2                     */
/* Catch a signal generated by a       */
/*   hardware exception                */
/* Philip Kayal                        */
/***************************************/

/**************************************************************/
/* Our hardware exception will be the user typing             */
/* 'kill -10 '. The signal generated              */
/* will be _SIGBUS.                                           */ 
/**************************************************************/
/* Alternatively, by changing FLAG to 1, the program will     */
/* automatically make the system call 'kill -10 '.       */
/**************************************************************/

/* Filename: pro.c */

/* Include the following C libraries: */
#include 
#include 
#include 
#include 
#include 
#include 

/* Define a constant string that may be a system call.    */
#define KILL "kill -10 "
#define FLAG 1

main()
{

/* Variable declarations */
  int j, a, b, c, sign;
  int pid;
  int choice;

  char term[] = KILL;
  char id[8]; /* PID as a string */

/* Declaration of signal-handling function. */
  void sig2func();

/* Initialization */
  j = 0;
  a = 0;
  b = 0;
  c = 0;
  sign = 0;
  pid = 0;
  choice = FLAG;

  printf ("\nProgram started OK \n");
  fflush(stdout);

/* If the signal _SIGBUS occurs, then do the function sig2func  */  
  if (signal(_SIGBUS, sig2func)== SIG_ERR) {
    printf ("\nSignal error\n");
  }

  if (choice == 0) {

/* Wait for user to kill process and cause bus error */
    printf("\nWaiting for user to execute a kill -10 on this process\n");
    fflush(stdout);
    sleep(50); 
  }

  else {

    sleep(5);

/* Get process id */
    pid = getpid();

/* Convert pid to a string */
    if ((sign = pid) < 0)
      pid  = -pid;
    j = 0;
    do {
      id[j++] = pid % 10 + '0';
    } while ((pid /= 10) > 0);
    if (sign < 0)
      id[j++] = '-';
    id[j] = '\0';

/* Reverse character order of string */
    for (a = 0, b = strlen(id) - 1; a < b; a++, b--) {
      c = id[a];
      id[a] = id[b];
      id[b] = c;
    }     

/* Combine 'kill -10' and 'id' */
    strcat(term,id);
    printf("\nTerminating process.\n");
    fflush(stdout);

/* Make system call to kill the process */
    system(term);
  }

  printf ("\nProgram finished OK \n");
  fflush(stdout);
  return;
}

void sig2func()
{
  int choice;

  choice = FLAG;

  printf("\nBus Error (_SIGBUS) caught,");
  fflush(stdout);
  if (choice == 0) {
    printf("\ndue to user executing 'kill -10 ',");
    fflush(stdout);
  }
  else {
    printf("\ndue to program executing 'kill -10 ',");
    fflush(stdout);
  }
  printf("\nExiting now.\n");
  fflush(stdout);
  exit(1);
}

/***************************************/
/* Physics 673 - Assignment #9         */ 
/* Due: November 27, 1996              */ 
/* Signals: Part 3                     */
/* Catch a signal from the kill(2)     */
/*   function                          */
/* Philip Kayal                        */
/***************************************/

/**************************************************************/
/* The kill function will be called by this program,          */
/* unducing the signal SIGTERM.                               */
/**************************************************************/

/* Filename: pro.c */

/* Include the following C libraries: */
#include 
#include 
#include 
#include 
#include 
#include 

main()
{

/* Variable declarations */
  int i, q;
  int pid, child;

  char ans;

/* Declaration of signal-handling function. */
  void sig3func();

/* Initialization */
  i = 0;
  q = 0;
  pid = 0;
  child = 0;

  printf ("\nProgram started OK \n");
  fflush(stdout);

/* If the signal SIGTERM occurs, then do the function sig3func  */
  if (signal(SIGTERM, sig3func) == SIG_ERR) {
    printf ("\nSignal error\n");
  }

/* Fork */
  pid = fork();

/* Error handling */

  if (pid < 0) {
    printf ("\nUnexpected pid value.\n");
    fflush(stdout);
  }
  else {

    if (pid == 0) {    /*** CHILD ***/

/* Have child process hang around */
      sleep(50);
    
      printf ("\nChild process terminated on its own\n");
      fflush(stdout);

      exit(1);
    }

    else {    /*** PARENT ***/

      printf ("\nThe parent process has PID %d \n", getpid() );
      fflush(stdout);
      printf ("\nParent process has started child with PID %d \n\n",pid);
      fflush(stdout);

      child = pid;
      while (i == 0) {

/* Prompt user every 5 seconds */
        sleep(5);
        printf("\nWould you like to kill the child? (y/n) "); 
        scanf(" %c", &ans);
      
        if (ans == 'y') {

          printf("\nTerminating child process: %d\n",child);
          fflush(stdout);

/* Use kill function to kill the child process */
          q = kill(child, SIGTERM);
          if (q == -1) {
            printf("\nError using kill function\n ");
          }
          i = 1;
        }
      }

/* Child process has finished */

      printf("\nParent sees that child process has terminated\n\n",pid);
      fflush(stdout);

      sleep(2);
   
      printf ("\nParent terminates\n");

      printf ("\nProgram finished OK \n");
      fflush(stdout);
    }

  }
  return;
}

void sig3func()
{
  printf("\nSIGTERM caught,");
  fflush(stdout);
  printf("\ndue to the function 'kill'.");
  fflush(stdout);
  printf("\nExiting now.\n");
  fflush(stdout);
  exit(1);
}


/***************************************/
/* Physics 673 - Assignment #9         */ 
/* Due: November 27, 1996              */ 
/* Signals: Part 4                     */
/* Catch a signal from the kill(1)     */
/*   command                           */
/* Philip Kayal                        */
/***************************************/

/*****************************************************************/
/* This program will make a system call "kill -9 "   */
/* to kill the child process,                                    */
/* which will induce the signal SIGTERM.                         */
/*****************************************************************/

/* Filename: pro.c */

/* Include the following C libraries: */
#include 
#include 
#include 
#include 
#include 
#include 

/* Define a constant string that will be a system call.    */
#define KILL "kill "

main()
{

/* Variable declarations */
  int i, j, x, k, sign;
  int a, b ,c;
  int pid, child;

  char ans;
  char term[] = KILL; 
  char id[8]; /* PID of child process as a string */

/* Declaration of signal-handling function. */
  void sig4func();

/* Initialization */
  i = 0;
  j = 0;
  x = 0;
  k = 0;
  a = 0;
  b = 0;
  c = 0;
  pid = 0;
  child = 0;

  printf ("\nProgram started OK \n");
  fflush(stdout);

/* If the signal SIGTERM occurs, then do the function sig4func  */
  if (signal(SIGTERM, sig4func) == SIG_ERR) {
    printf ("\nSignal error\n");
  }

/* Fork */
  pid = fork();

/* Error handling */

  if (pid < 0) {
    printf ("\nUnexpected pid value.\n");
    fflush(stdout);
  }
  else {

    if (pid == 0) {    /*** CHILD ***/

/* Have child process hang around */
      sleep(50);
    
      printf ("\nChild process terminated on its own\n");
      fflush(stdout);
    }

    else {    /*** PARENT ***/

      printf ("\nThe parent process has PID %d \n", getpid() );
      fflush(stdout);
      printf ("\nParent process has started child with PID %d \n\n",pid);
      fflush(stdout);

      child = pid;
      while (i == 0) {

/* Prompt user every 5 seconds */
        sleep(5);
        printf("\nWould you like to kill the child? (y/n) "); 
        scanf(" %c", &ans);
      
        if (ans == 'y') {

/* Convert child pid to a string */
          if ((sign = pid) < 0)
            pid  = -pid;
          j = 0;
          do {
            id[j++] = pid % 10 + '0';
          } while ((pid /= 10) > 0);
          if (sign < 0)
            id[j++] = '-';
          id[j] = '\0';

/* Reverse character order of string */
          for (a = 0, b = strlen(id) - 1; a < b; a++, b--) {
            c = id[a];
            id[a] = id[b];
            id[b] = c;
          }     

/* Combine 'Kill -9' and 'id' */
          strcat(term,id);
          printf("\nTerminating child process: %d\n",child);
          fflush(stdout);

/* Make system call to kill the child process */
          system(term);
          i = 1;
        }
      }

/* Child process has finished */

      sleep(2);

      printf("\nParent sees that child process has terminated\n\n",pid);
      fflush(stdout);

      printf ("\nParent terminates\n");
      fflush(stdout);

      printf ("\nProgram finished OK \n");
      fflush(stdout);
    }

  }
  return;
}

void sig4func()
{
  printf("\nSIGTERM caught,");
  fflush(stdout);
  printf("\ndue to the system call 'kill -9 '.");
  fflush(stdout);
  printf("\nExiting now.\n");
  fflush(stdout);
  exit(1); /* Exit the child process */
}
/***************************************/
/* Physics 673 - Assignment #9         */
/* Due: November 27, 1996              */
/* Signals: Part 5                     */
/* Catch a signal generated by a       */
/*   hardware condition                */
/* Philip Kayal                        */
/***************************************/

/**************************************************************/
/* Our hardware condition will be a division by zero,         */
/* which will induce a floating point exception (SIGFPE).     */
/**************************************************************/

/* Filename: pro.c */

/* Include the following libraries: */
#include 
#include 
#include 
#include 
#include 
#include 

main()
{

/* Variable declarations */
  int num, zero, ohoh;

/* Declaration of signal-handling function. */
  void sig5func();

/* Initialization */
  num = 5;
  zero = 0;
  ohoh = 0;

  printf ("\nProgram started OK \n");
  fflush(stdout);

/* If the signal SIGFPE occurs, then do the function sig5func  */
  if (signal(SIGFPE, sig5func) == SIG_ERR) {
    printf ("\nSignal error\n");
  }

  sleep(3); 

/* Division by zero */
  ohoh = num / zero;

  printf ("\nProgram finished OK \n");

  return;
}

void sig5func()
{
  printf("\nFloating Point Exception (SIGFPE) caught,");
  fflush(stdout);
  printf("\nso core dump is prevented by exiting now.\n");
  fflush(stdout);
  exit(1);
}

/***************************************/
/* Physics 673 - Assignment #9         */ 
/* Due: November 27, 1996              */ 
/* Signals: Part 6                     */
/* Catch a software generated signal   */
/* Philip Kayal                        */
/***************************************/

/**************************************************************/
/* This program will write on a pipe which does not get       */
/* read. This will induce a _SIGPIPE signal.                  */
/**************************************************************/

/* Filename: sig.c */

/* Include the following C libraries:                  */
/* (these probably aren't all necessary, but may be    */
/*  required in future versions of this program.)      */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

main()
{

/* Variable declarations */

  int pipe1fd[2]; /* Pipe 1 : parent-to-child communication   */

/* Declaration of signal-handling function. */
  void sig6func(); 

  printf ("\nProgram started OK \n");
  fflush(stdout);

/* If the signal _SIGPIPE occurs, then do the function sig6func  */
  if (signal(_SIGPIPE, sig6func) == SIG_ERR) {
    printf ("\nSignal error\n");
  }

/* Create pipe 1. The "channels" are open for read and write.   */
/* Error handling is included. */

  if (pipe(pipe1fd) < 0) {
    printf ("\nPipe error");
    fflush(stdout); 
  }
  else {
    printf("\nPipe created OK\n");
  }

/* Close read for pipe 1 */
  close(pipe1fd[0]);

/* Send message to nowhere */
  write(pipe1fd[1], "I am hungry.\n", 13);

  sleep(2);

  printf ("\nProgram finished OK \n");
  
  return;
}

void sig6func()
{  
  printf("\n_SIGPIPE signal caught,");
  fflush(stdout);
  printf("\ndue to writing on a pipe with no one to read it.\n");
  fflush(stdout);
}