title: Parent process and child process synchronization
body: <p>I have a project that requires me to use signal and fork to read content of a file and write it back to the stdout (low level I/O). I should split the work of reading and writing between parent and child process, and I should begin the parent process first to read and write the content of the file. After the parent finish, I should send signal SIGUSR1 to the child process so it can begin to read and write the next block of data. 
  My reading and writing part runs ok, but I have problem with the signal and process parts. When I run my program, it display the correct output but it never terminates.
  Could somebody check what is wrong with my code?</p>
  
  <p>Here is what I got so far:</p>
  
  <pre><code>#define _XOPEN_SOURCE 600
  
  #include &lt;limits.h&gt; /* For LONG_MAX */
  #include &lt;fcntl.h&gt; /*For open()*/
  #include &lt;unistd.h&gt; /*For close(), read(), write(), nice()*/
  #include &lt;stdlib.h&gt; /*For exit()*/
  #include &lt;stdio.h&gt; /*For fprintf(),perror()*/
  #include &lt;signal.h&gt; /*For signal()*/
  #include &lt;sys/types.h&gt; /* For pid_t */
  #include &lt;sys/wait.h&gt; /* For wait() */
  
  void my_handler(int);
  void displayUsage(FILE *, const char *);
  
  int main(int argc, char **argv) {
  
          char c[BUFSIZ]; /* To hold the string that has been read from the file */
          int fd; /* file descriptor */
          int n;
          long int nBytes; /* To hold the number of bytes to read */
          pid_t pid;
          int child_status;
  
          /* Display usage if user use this process wrong */
          if(argc != 3){
              displayUsage(stderr, argv[0]);
              exit(1);
          }
  
          /* Convert argv[1] to long - number of bytes to read */
          nBytes = strtol(argv[1], NULL, 10);
          if((nBytes &lt;= 0) || (nBytes &gt; INT_MAX)){
              fprintf(stderr, "Bufferize %s is not a positive integer\n",
               argv[1]);
              exit(2);
          }
  
          /* Open a file */
          if((fd = open(argv[2],O_RDONLY,0)) &lt; 0){
             perror(argv[2]);
             exit(3);
          }
  
          /* Attempt to register a signal handler */
          if(signal(SIGUSR1, my_handler) == SIG_ERR){
             perror("Could not set a handler for SIGUSR1");
             exit(4);
          }
  
          /* lowering the process priority */
          if(nice(40) &lt; 0){
             perror("Cannot lower the priority");
             exit(5);
          }
  
          /* Create a new process */
          pid = fork();
          if(pid &lt; 0){
             exit(6);
          }
          /* Allocating memory space for string/data to be read from the file
          if(!(c = malloc(nBytes))){
             perror("ERROR");
             exit(4);
          }*/
  
          if(pid == 0){
             pause();
             /* I'm the child */
             printf("Child's turn!\n");
  
             /* Read The File */
             while((n = read(fd, c, nBytes)) != 0){
                    /* Write content of 'c' to the stdout */
                    if(write(STDOUT_FILENO, c, n) &lt; 0){
                           perror("Write Error!\n");
                           exit(7);
                    }
             }
             kill(pid,SIGUSR1);
  
          }
          else{
             /* I'm the parent */
             printf("Parent's turn!\n");
             /* Read The File */
             while((n = read(fd, c, nBytes)) != 0){
                   /* Write content of 'c' to the stdout */
                   if(write(STDOUT_FILENO, c, n) &lt; 0){
                            perror("Write Error!\n");
                            exit(7);
                   }
             }
             /* Reap the child */
             wait(&amp;child_status);
             kill(pid, SIGUSR1);
           }
           pause();
  
           /* Close the file */
           if(close(fd) &lt; 0){
              perror(argv[2]);
              exit(8);
           }
  
           exit(0);
  }
  
  void displayUsage(FILE *fp, const char *arg){
  
          fprintf(fp, "Usage: %s n filename\n", arg);
          fprintf(fp, "where\n");
          fprintf(fp, 
              "\tn\tNumber of bytes to read and write in each \"block\".\n");
          fprintf(fp,"\tfilename\tName of file to be catted.\n");
  }
  
  void my_handler(int sig){
          /* Re-registering the handler */
          if(signal(SIGUSR1, my_handler) == SIG_ERR){
               perror("Could not set a handler for SIGUSR1");
               exit(4);
          }
  
          /*if(isParent == 1){
               printf("Parent's turn!\n");
            }
            else{
               printf("Child's turn!\n");
            }*/
  }
  </code></pre>