title: Unix - Sort from child blocking
body: <p>I was trying to complete an exercise when I found some problems that I cannot understand.
  First one: 
  I'm trying to sort a file using system(string), where the string contains: <strong>/usr/bin/sort -n -o %s %s</strong>. %s is the path which I read from the parent through a pipe, and printing the string I see that is correct. Everything seems working if I remove the -o %s. If I add it, the program gets stucked on the sort. 
  Here the code:</p>
  
  <pre><code>str=strcat(dir, str);
  printf("    %s       \n", str);
  sprintf(ssys, "/usr/bin/sort -n -o %s %s", str, str);
  printf("     1111    \n");
  system(ssys);
  printf("     2222   \n");
  </code></pre>
  
  <p>And the output is:</p>
  
  <p><strong>/home/dio/Desktop/Operating-System-PoliTo/Lab6/ex2/texts/1.txt</strong></p>
  
  <p><strong>1111</strong>    </p>
  
  <p>As you can see, it doesn't reach the third printf, but just when I press CTRL+c to kill the process, even if the file isn't sorted. I cannot understand why, because if I run it and check with <strong>ps</strong> I get the <strong>sort</strong> process running.Seems like it is waiting for the parent to finish but it doesn't sort anyway.</p>
  
  <p>This is the whole code:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;sys/types.h&gt;
  
  static void sig_handler (int);
  
  static void sig_handler (int signo)
  {
          if (signo == SIGPIPE)
                  exit(0);
  }
  
  int main (int argc, char **argv)
  {
  
          signal(SIGPIPE, sig_handler);
  
          if (argc&lt;3)
          {
                  printf("Too little arguments");
                  return 1;
          }
  
          int c=atoi(argv[1]);
          int *pids=malloc(sizeof(int)*c);
          int i=0, num_char_str, id, line_sort, request_pipe[c][2], data_pipe[c][2], answer_pipe[c][2];
          pid_t pid;
          char cR, cW;
          char *dir=malloc(strlen(argv[2])+1);
          char *str=malloc(strlen(argv[2])*10);
          char *ssys=malloc(strlen(argv[2])*10);
          FILE* fpp;
          FILE* fp;
  
          strcpy(dir, argv[2]);
          sprintf(str, "ls %s &gt; list.txt",  dir);
          system(str);
          for(i=0; i&lt;c; i++)
          {
                  if (pipe(request_pipe[i]) == -1)
                          return 2;
                  if (pipe(data_pipe[i]) == -1)
                          return 2;
                  if (pipe(answer_pipe[i]) == -1)
                          return 2;
          }
          for(i=0; i&lt;c; i++)
          {
                  pid=fork();
                  if(pid&gt;0)
                          pids[i]=pid;
                  if (pid == -1)
                  {
                          printf("error forking");
                          return 3;
                  }
                  if (pid==0)
                          break;
          }
      if (pid&gt;0) /// parent
          {
                  for(i=0; i&lt;c; i++)
                  {
                          close(answer_pipe[i][1]);  /// close answer pipe on writing
                          close(request_pipe[i][1]);  /// close request pipe on writing
                          close(data_pipe[i][0]);  /// close data pipe on reading
                  }
                  fp=fopen("list.txt", "r");
                  if (fp==NULL)
                          return 3;
                  i=0;
                  while (fgets(str, sizeof(str), fp)!=NULL)
                  {
                          /// wait for ask
                          read(request_pipe[i][0], &amp;cR, 1);
                          /// sending first the number of characters to read
                          /// and then the file name
                          num_char_str=(strlen(str) +1);
                          write(data_pipe[i][1], &amp;num_char_str, sizeof(int));
                          write(data_pipe[i][1], str, num_char_str);
                          /// read the answer
                          read(answer_pipe[i][0], &amp;id, sizeof(int));
                          //pids[i]=id;
                          read(answer_pipe[i][0], &amp;line_sort, sizeof(int));
                          if (i==c-1)
                                  i=-1;
                          i++;
                  }
                  /// sending termination signal to children
                  for (i=0; i&lt;c; i++)
                          kill(pids[i], SIGPIPE);
                  /// producing all_sorted.txt
                  strcpy(str, "touch all_sorted.txt");
                  system(str);
                  sprintf(str, "find %s -name \"*.txt\" -exec cat \"{}\"\";\" &gt; all_sorted.txt", dir);
                  system(str);
                  /// sorting all_sorted
  
          }
          if (pid == 0) /// child
          {
                  close(answer_pipe[i][0]);  /// close answer pipe on reading
                  close(request_pipe[i][0]);  /// close request pipe on reading
                  close(data_pipe[i][1]);  /// close data pipe on writing
                  while (1)
                  {
                          /// send request to parent
                          write(request_pipe[i][1], &amp;cW, 1);
                          /// read length of string
                          read(data_pipe[i][0], &amp;num_char_str, sizeof(int));
                          /// read the file name
                          read(data_pipe[i][0], str, num_char_str);
                          /// sorting
                          str=strcat(dir, str);
                          sprintf(ssys, "/usr/bin/sort -n -o %s %s", str, str);
  printf("     1111    \n");
                          system(ssys);
  printf("     2222   \n");
                          /// sending back data
                          id=getpid(); 
                          write(answer_pipe[i][1], &amp;id, sizeof(int));
                          //sprintf(str, "wc -l %s/%s", dir, str);
                          //fpp=popen(str, "r");
                          //fscanf(fpp, "%d", &amp;line_sort);
                          //pclose(fpp);
                          line_sort=1;
                          write(answer_pipe[i][1], &amp;line_sort, sizeof(int));
                  }
          }
  
          return 0;
  
  }
  </code></pre>