/***********************************/
/* Physics 673 - Assignment #8     */ 
/* Due: November 20, 1996          */ 
/* Interprocess Communication      */
/* Part 1 - Using pipes            */
/* Philip Kayal                    */
/***********************************/

/* Filename: ic.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 

/* Define a constant string that will be a system call. */
/* This command will search through pkayal's processes */
/* for any processes with the name "ic.out".          */

#define PS "ps -lu pkayal | grep ic.out"

main()
{

/* Variable declarations */

  int x, k, n, m;
  int pid;
  int pipe1fd[2]; /* Pipe 1 : parent-to-child communication   */
  int pipe2fd[2]; /* Pipe 2 : child-to-parent communication   */

/* We are going to pass cute messages between child and parent.       */
/* The parent will tell the child "Behave yourself.", and the child   */
/* will tell the parent "I am humgry."                                */
/*                                                                    */
/* Each of these strings is less than 20 characters, so we define     */
/* a sufficiently long string in each case.                           */

  char ctop[20];  /* child-to-parent */
  char ptoc[20];  /* parent-to-child */

  char proc[] = PS; 

/* Initialization */
  n = 0;
  m = 0;
  x = 0;
  k = 0;
  pid = 0;

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

/* The will be two pipes. Pipe 1 goes from parent to child.   */
/*                        Pipe 2 goes from child to parent.   */

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

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

/* Create pipe 2. The "channels" are open for read and write.   */
/* Error handling is included. */
  
  if (pipe(pipe2fd) < 0) {
    printf ("\nPipe error.\n");
    fflush(stdout);
  }

/* Fork */
  pid = fork();

/* Error handling for fork */

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

    if (pid == 0) {    /*** CHILD ***/
      sleep(1);

/* Have child process show that it is running.     */
      printf ("Child process %d is running\n", getpid() );
      fflush(stdout);

/* Close child's write for pipe 1 */
      close(pipe1fd[1]);

/* Close child's read for pipe 2 */
      close(pipe2fd[0]);

/* Read message from parent */
      n = read(pipe1fd[0], ptoc, 17);
      
/* Error handling - check number of bytes */
      if (n <= 0) {
        printf ("\nRead error (in child).\n");
        fflush(stdout);
      }

      printf("\nChild hears from parent: %s", ptoc);
      fflush(stdout);  

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

/* Make child process hang around a bit     */
      while (k < 1) {
        sleep(4);
        k = k + 1;
      }

      printf ("\nChild process terminated on its own\n\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);

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

/* Close parent's write for pipe 2 */
      close(pipe2fd[1]);

/* Send message to child */   
      write(pipe1fd[1], "Behave yourself.\n", 17);

/* Read message from child */
      m = read(pipe2fd[0], ctop, 13);

/* Error handling - check number of bytes */
      if (m <= 0) {
        printf ("\nRead error (in parent).\n");
        fflush(stdout);
      }

      printf("\nParent hears from child: %s\n", ctop);
      fflush(stdout);  

/* Make system call to list processes.                  */
/* At this point, the parent and child processes        */
/* should both be shown.                                */

/*      system(proc);
      fflush(stdout); */

/* Use waitpid to wait for child process to finish */

      sleep(2);

      while (x == 0) {
/* Make system call to list processes.                      */
/* This will show that the zombie exists for a short time.  */
        
        system(proc);
        fflush(stdout);

        if (waitpid(pid,0,WNOHANG) == 0) {
          sleep(5);
        }
        else {
          x = 1;
        }
      }

/* Child process has finished */

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

/* Make system call to list processes.                     */
/* At this point, only the parent process should be shown. */

      system(proc);
      fflush(stdout);

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

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

  }
  return;
}
/***********************************/
/* Physics 673 - Assignment #8     */ 
/* Due: November 20, 1996          */ 
/* Interprocess Communication      */
/* Part 2 - Using FIFOs            */
/* Philip Kayal                    */
/***********************************/

/* Filename: ic.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 

/* Define a constant string that will be a system call. */
/* This command will search through pkayal's processes  */
/* for any processes with the name "ic.out".            */

#define PS "ps -lu pkayal | grep ic.out"

/* Define the permissions for the FIFO   */
#define PERMS 00600  /* User has read/write permissions  */

main()
{

/* Define the path and filename of the FIFO.                 */
/* We will use the file "myfifo" in the directory "place'.   */
  const char FileName[40] = "/dsk5/pkayal/p673/ic4/place/myfifo";

/* Variable declarations */

  int x, k, n, m, a, b;
  int fd;
  int pid;

/* We are going to pass cute messages between child and parent.       */
/* The parent will tell the child "Behave yourself.", and the child   */
/* will tell the parent "I am humgry."                                */
/*                                                                    */
/* Each of these strings is less than 20 characters, so we define     */
/* a sufficiently long string in each case.                           */

  char ctop[20];  /* child-to-parent */
  char ptoc[20];  /* parent-to-child */

  char proc[] = PS; 

/* Initialization */
  n = 0;
  m = 0;
  x = 0;
  k = 0;
  a = 0;
  b = 0;
  pid = 0;

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

/* Delete the FIFO from a previous run, if it exists. */

  unlink(FileName);

/* Create the FIFO. Error handling is included. */

  if ((a = mkfifo(FileName,PERMS)) == 0) {
    printf ("\nFIFO created OK\n");
    fflush(stdout); 
  }
  else {
    printf ("\nFIFO error\n");
    fflush(stdout);
  }

/* Open the FIFO. */
    fd = open(FileName, O_RDWR);
      
    if (fd < 0) {
      printf ("\nError opening file");
      fflush(stdout);
    }
    else {
      printf ("\nFile opened OK\n");
      fflush(stdout);
    }

/* Fork */
  pid = fork();

/* Error handling for fork */

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

    if (pid == 0) {   /*** CHILD ***/
      sleep(1);

/* Have child process show that it is running.     */
      printf ("Child process %d is running\n", getpid() );
      fflush(stdout);

/* Read message from parent */
      n = read(fd, ptoc, 17); 
      
/* Error handling - check number of bytes that are read   */
      if (n <= 0) {
        printf ("\nRead error (in child).\n");
        fflush(stdout);
      }

      printf("\nChild hears from parent: %s", ptoc);
      fflush(stdout); 

      sleep(5);

/* Send message to parent */
      a = write(fd, "I am hungry.\n", 13);

/* Error handling - check number of bytes that are written   */

      if (a <= 0) {
        printf ("\nWrite error (in child).\n");
        fflush(stdout);
      }

/* Make child process hang around a bit     */
      while (k < 1) {
        sleep(4);
        k = k + 1;
      }

      printf ("\nChild process terminated on its own\n\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);

      sleep(5);

/* Send message to child */   
      b = write(fd, "Behave yourself.\n", 17); 

/* Error handling - check number of bytes that are written   */

      if (b <= 0) {
        printf ("\nWrite error (in parent).\n");
        fflush(stdout);
      }

      sleep(5);

/* Read message from child */
      m = read(fd, ctop, 13);

/* Error handling - check number of bytes that are read   */
      if (m <= 0) {
        printf ("\nRead error (in parent).\n");
        fflush(stdout);
      }

      printf("\nParent hears from child: %s\n", ctop);
      fflush(stdout);  

/* Use waitpid to wait for child process to finish */

      sleep(2);

      while (x == 0) {
/* Make system call to list processes.                      */
/* This will show that the zombie exists for a short time.  */
        
        system(proc);
        fflush(stdout);

        if (waitpid(pid,0,WNOHANG) == 0) {
          sleep(5);
        }
        else {
          x = 1;
        }
      }

/* Child process has finished */

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

/* Make system call to list processes.                     */
/* At this point, only the parent process should be shown. */

      system(proc);
      fflush(stdout);

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

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

/* Close the FIFO   */

  close(fd);

  }
  return;
}
/***********************************/
/* Physics 673 - Assignment #8     */ 
/* Due: November 20, 1996          */ 
/* Interprocess Communication      */ 
/* Part 3 - Using Shared Memory    */ 
/* Philip Kayal                    */
/***********************************/

/****************************************************/
/* I tried and tried and tried, but couldn't get    */
/* shared memory to work. There is some problem     */
/* in reading and writing to the shared memory.     */
/* Anyways, this is what I have.                    */
/****************************************************/

/* Filename: ic.c */

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

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

/* Define a constant string that will be a system call. */
/* This command will search through pkayal's processes  */
/* for any processes with the name "ic.out".            */

#define PS "ps -lu pkayal | grep ic.out"

/* We are going to pass the messages "Behave yourself." from        */
/* The parent to the child.                                         */

#define BH "Behave yourself."

/* Define the size of the shared memory */
#define SHM_SIZE 100

/* Define the shared memory permissions */
#define SHM_PERM (SHM_R | SHM_W)  /* User read and write */

main()
{

/* Variable declarations */

  int x, k, a, b;
  int pid;
  int shmid;  /* Shared memory identifier */

/* We are going to pass cute messages between child and parent.       */
/* The parent will tell the child "Behave yourself.", and the child   */
/* will tell the parent "I am humgry."                                */

  char mess1[] = BH; 

  char proc[] = PS; 

  char *shmptr1;
  char *shmptr2;

/* Initialization */
  a = 0;
  b = 0;
  x = 0;
  k = 0;
  pid = 0;
  shmid = 0;

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

/* Obtain a shared memory identifier. */

  if ((shmid = shmget(IPC_PRIVATE,SHM_SIZE,SHM_PERM)) > 0) {
    printf ("\nShared memory created OK\n");
    fflush(stdout); 
  }
  else {
    printf ("\nShared memory error\n");
    fflush(stdout);
  }

/* Fork */
  pid = fork();

/* Error handling for fork */

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

    if (pid == 0) {   /*** CHILD ***/
      sleep(1);

/* Have child process show that it is running.     */
      printf ("Child process %d is running\n", getpid() );
      fflush(stdout);

/* Connect child to shared memory */
      shmptr1 = shmat(shmid, (char *)0, 0); 

/* Error handling - check that child attached to shared memory   */
      if (shmptr1 == (void *) -1) {
        printf ("\nError: Child not attached to shared memory.\n");
        fflush(stdout);
      }
      else {
        printf ("\nChild attached to shared memory OK.\n");
        fflush(stdout);
      } 

      printf("\nChild hears from parent: %s\n", *shmptr1);
      fflush(stdout); 

      sleep(5);

/* Make child process hang around a bit     */
      while (k < 1) {
        sleep(4);
        k = k + 1;
      }

      printf ("\nChild process terminated on its own\n\n");
      fflush(stdout);

/* Detach shared memory */
      
      a = shmdt (shmptr1); 

/* Error handling for detaching shared memory */
      
      if (a == 0) {
        printf ("\nChild: Shared memory detached OK.\n");
        fflush(stdout);
      }
      else {
        printf ("\nChild: Error detaching shared memory.\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);

/* Connect parent to shared memory */
      shmptr2 = shmat(shmid, (char *)0, 0);  

/* Error handling - check that parent attached to shared memory   */
      if (shmptr2 == (void *) -1) {
        printf ("\nError: Parent not attached to shared memory.\n");
        fflush(stdout);
      }
      else {    
        printf ("\nParent attached to shared memory OK.\n");
        fflush(stdout);
      } 

/* Send message to shared memory (for child) */   
      
      shmptr1 = mess1;

      sleep(5);

/* Use waitpid to wait for child process to finish */

      sleep(2);

      while (x == 0) {
/* Make system call to list processes.                      */
/* This will show that the zombie exists for a short time.  */
        
        system(proc);
        fflush(stdout);

        if (waitpid(pid,0,WNOHANG) == 0) {
          sleep(5);
        }
        else {
          x = 1;
        }
      }

/* Child process has finished */

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

/* Make system call to list processes.                     */
/* At this point, only the parent process should be shown. */

      system(proc);
      fflush(stdout);

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

/* Detach shared memory */

      b = shmdt (shmptr2); 

/* Error handling for detaching shared memory */

      if (b == 0) {
        printf ("\nParent: Shared memory detached OK.\n");
        fflush(stdout);
      }
      else {
        printf ("\nParent: Error detaching shared memory.\n");
        fflush(stdout);
      }   

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

  }
  return;
}
/**********************************************/
/* Physics 673 - Assignment #8                */ 
/* Due: November 20, 1996                     */ 
/* Interprocess Communication                 */
/* Part 4 - Using Message Passing Queues      */
/* Philip Kayal                               */
/**********************************************/

/****************************************************/
/* I tried and tried and tried, but couldn't get    */
/* message queues to work. There is some problem    */
/* in sending and receiving messages.               */
/* Anyways, this is what I have.                    */
/****************************************************/

/* Filename: ic.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 
#include 

/* Define a constant string that will be a system call. */
/* This command will search through pkayal's processes  */
/* for any processes with the name "ic.out".            */

#define PS "ps -lu pkayal | grep ic.out"

main()
{

/* Define the path and filename of the FIFO.     */

  struct message {
    long mtype;
    char mess[20];
  } mess1, mess2, mess3, mess4;

/* Variable declarations */

  int x, y, k, c, d, a, b;
  int pid;
  int msqid; /* The message queue ID */

  char proc[] = PS; 

  void *ptr1;
  void *ptr2;
  void *ptr3;
  void *ptr4;

/* Initialization */
  c = 0;
  d = 0;
  k = 0;
  x = 0;
  y = 0;
  a = 0;
  b = 0;
  pid = 0;
  msqid = 0;

/* We are going to pass cute messages between child and parent.       */
/* The parent will tell the child "Behave yourself.", and the child   */
/* will tell the parent "I am hungry."                                */

  mess1.mtype = 40;
  strcpy(mess1.mess, "Behave yourself");

  ptr1 = &mess1; 

  mess2.mtype = 41;  
  strcpy(mess2.mess, "I am hungry");

  ptr2 = &mess2;

  ptr3 = &mess3;

  ptr4 = &mess4;

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

/* Create a new message queue */

  msqid = msgget(IPC_PRIVATE,0);

/* Error handling for message queue creation  */

  if (msqid < 0) {
    printf ("\nError creating queue.\n");
    fflush(stdout);
  }
  else {
    printf ("\nQueue created OK.\n");
    fflush(stdout);
  }

/* Fork */
  pid = fork();

/* Error handling for fork */

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

    if (pid == 0) {   /*** CHILD ***/
      sleep(3);

/* Have child process show that it is running.     */
      printf ("Child process %d is running\n", getpid() );
      fflush(stdout);

/* Receive message from parent.        */
      a = msgrcv(msqid,ptr3,20,40,IPC_NOWAIT);

/* Error handling for message reception */

      if (a < 0) {
        printf ("\nChild: Error receiving message.\n");
        fflush(stdout);
      }
      else {
        printf ("\nChild: Message received OK.\n");
        fflush(stdout);
      }

      ptr3 = &mess3;

      printf("\nChild hears from parent: %s", mess3.mess);
      fflush(stdout); 

      sleep(5);

/* Send message to parent */

      x = msgsnd(msqid,ptr2,20,0);

/* Error handling for message sending */

      if (x < 0) {
        printf ("\nChild: Error sending message.\n");
        fflush(stdout);
      }
      else {
        printf ("\nChild: Message sent OK.\n");
        fflush(stdout);
      }

/* Make child process hang around a bit     */
      while (k < 1) {
        sleep(4);
        k = k + 1;
      }

      printf ("\nChild process terminated on its own\n\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);

      sleep(5); 

/* Send message to child */   

      y = msgsnd(msqid,ptr1,20,0);

/* Error handling for message sending */

      if (y < 0) {
        printf ("\nParent: Error sending message.\n");
        fflush(stdout);
      }   
      else {
        printf ("\nParent: Message sent OK.\n");
        fflush(stdout);
      }   

      sleep(5);

/* Read message from child */

      b = msgrcv(msqid,ptr4,41,20,0);

/* Error handling for message reception */
    
      if (b < 0) {
        printf ("\nParent: Error receiving message.\n");  
        fflush(stdout);
      }
      else {
        printf ("\nParent: Message received OK.\n");
        fflush(stdout);
      }

      ptr4 = &mess4;

      printf("\nParent hears from child: %s\n", mess4.mess);
      fflush(stdout); 

/* Use waitpid to wait for child process to finish */

      sleep(2);

      while (c == 0) {
/* Make system call to list processes.                      */
/* This will show that the zombie exists for a short time.  */
        
        system(proc);
        fflush(stdout);

        if (waitpid(pid,0,WNOHANG) == 0) {
          sleep(5);
        }
        else {
          c = 1;
        }
      }

/* Child process has finished */

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

/* Make system call to list processes.                     */
/* At this point, only the parent process should be shown. */

      system(proc);
      fflush(stdout);

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

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

/* Remove the message queue from the system.   */

  d = msgctl(msqid, IPC_RMID, 0);

/* Error handling for message queue removal */
      
  if (d == 0) {
    printf ("\nMessage queue removed OK.\n");
    fflush(stdout);
  } 
  else {
    printf ("\nError removing message queue.\n");
    fflush(stdout);
  }  

  }
  return;
}