title: C Detect fault in popen child process
body: <p>I'm using <code>popen</code> to read the output of a third party program.  I'd like to detect and restart things if the sub-program fails.</p>
  
  <p>How would I do that?  If the child dies, the process didn't exit normally and therefore can't use <code>WEXITSTATUS</code> to check.</p>
  
  <p>Is there another way?</p>
  
  <p>Here's a simple example:</p>
  
  <p><strong>PINGER.C</strong></p>
  
  <pre><code>#include &lt;string.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  
  int
  main(int argc, char **argv)
  {
      int i = 0;
      while (1)
      {
          //fprintf(stderr, "StdErr %d\n", i);
          printf("stdout %d\n", i++);
          fflush(stdout);
  
          if (i == 5)
              i = i / 0; // Die a horrible death
  
          sleep(1);
      }
  }
  </code></pre>
  
  <p><strong>WATCHER.C</strong></p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/wait.h&gt;
  
  int
  main(int argc, char **argv)
  {
      char *cmd = "./pinger";
      printf("Running '%s'\n", cmd);
  
      FILE *fp = popen(cmd, "r");
      if (!fp)
      {
          perror("popen failed:");
          exit(1);
      }
  
      char inLine[1024];
      int  bytesRead = 0;
      int  i = 0;
  
      while (fgets(inLine, sizeof(inLine), fp) != NULL)
      {
          int len = strlen(inLine);
          if (inLine[len-1] == '\n')
              inLine[len-1] = '\0';
  
          printf("Received: '%s'\n", inLine);
      }
  
      printf("feof=%d ferror=%d: %s\n", feof(fp), ferror(fp), strerror(errno));
  
      int rc = pclose(fp);
      printf("pclose returned: %d. IFEXITED=%d\n", rc, WIFEXITED(rc));
  }
  </code></pre>
  
  <p>Here's the output:</p>
  
  <pre><code>$ ./popenTest
  calling popen
  Running './pinger'
  pipe open
  Received: 'stdout 0'
  Received: 'stdout 1'
  Received: 'stdout 2'
  Received: 'stdout 3'
  Received: 'stdout 4'
  feof=1 ferror=0: Success
  pclose returned: 8. IFEXITED=0 EXITSTATUS=0
  </code></pre>
  
  <p>(<a href="https://www.ibm.com/support/knowledgecenter/en/SSB23S_1.1.0.15/gtpc2/cpp_wexitstatus.html" rel="nofollow noreferrer">According to this post</a>, you actually can't use <code>WEXITSTATUS</code> if the command didn't exit normally, but I tried anyway)</p>