title: proc_open hangs when trying to read from a stream
body: <p>I've encountered the issue with <code>proc_open</code> on Windows, when trying to convert a wmv file (to flv), using <code>ffmpeg</code>, however I suspect I'll encounter the same scenario whenever certain conditions occur.<br/>
  Basically my code is as follows:</p>
  
  <pre><code>$descriptorspec = array
  (
      array("pipe", "r"),
      array("pipe", "w"),
      array("pipe", "w")
  );
  
  $pipes = array();
  $procedure = proc_open('cd "C:/Program Files/ffmpeg/bin" &amp;&amp; "ffmpeg.exe" -i "C:/wamp/www/project/Wildlife.wmv" -deinterlace -qdiff 2 -ar 22050 "C:/wamp/www/project/Wildlife.flv"', $descriptorspec, $pipes);
  var_dump(stream_get_contents($pipes[1]));
  </code></pre>
  
  <p>Now, this code will cause PHP to hang indefinitely (it doesn't matter if instead of <code>stream_get_contents</code> I'll use <code>fgets</code> or <code>stream_select</code>, the behavior is consistent).</p>
  
  <p>The reason for it (I suspect) is that, while STDOUT stream is open succesfully, the process doesn't write anything to it (even though running the same command in cmd displays output) and as such, trying to read from such stream, would cause the same issue as described <a href="https://stackoverflow.com/questions/20684777/php-stream-get-contents-hangs-at-the-end-of-the-stream">here</a>, so - PHP waits for the stream to have anything in it, process doesn't write anything to it.</p>
  
  <p>However (additional fun), setting <code>stream_set_timeout</code> or <code>stream_set_blocking</code> doesn't have any effect.</p>
  
  <p>As such - can somebody confirm/deny on what is going on, and, if possible, show how can I cater for such situation? I've looked at PHP bugs, and all <code>proc_open hangs</code> ones seem to be fixed.</p>
  
  <p>For time being I've implemented such solution:</p>
  
  <pre><code>$timeout = 60;
  while (true) {
      sleep(1);
  
      $status = proc_get_status($procedure);
      if (!$status['running'] || $timeout == 0) break;
  
      $timeout--;
  }
  </code></pre>
  
  <p>However, I'd really not like to rely on something like this as:</p>
  
  <ol>
  <li>I will have processes that run for longer than a minute - such processes will be falsely reported to be of the above mentioned type</li>
  <li>I want to know when the ffmpeg has finished converting the video - currently I'll only know that process is still running after a minute, and I can't really do anything to check if there's any output (as it will hang PHP). </li>
  </ol>
  
  <p>Also, I don't really want to wait a full minute for the process to be checked (for example - converting the given video from command line takes &lt;10s), and I'll have videos that take more time to be converted.</p>
  
  <hr>
  
  <p>Per comment from @Sjon, here's <code>stream_select</code> I was using, which blocks due to same issue - STDOUT not being written to:</p>
  
  <pre><code>$descriptorspec = array
  (
      array("pipe", "r"),
      array("pipe", "w"),
      array("pipe", "w")
  );
  
  $pipes = array();
  $procedure = proc_open('cd "C:/Program Files/ffmpeg/bin" &amp;&amp; "ffmpeg.exe" -i "C:/wamp/www/sandbox/Wildlife.wmv" -deinterlace -qdiff 2 -ar 22050 "C:/wamp/www/sandbox/Wildlife.flv"', $descriptorspec, $pipes);
  
  $read = array($pipes[0]);
  $write = array($pipes[1], $pipes[2]);
  $except = array();
  
  while(true)
  if(($num_changed_streams = stream_select($read, $write, $except, 10)) !== false)
  {
      foreach($write as $stream)
          var_dump(stream_get_contents($stream));
  
      exit;
  }
  else
      break;
  </code></pre>
  
  <hr>
  
  <p>Per conversation with @Sjon - reading from buffered streams on Windows is broken. The solution in the end is to use stream redirection via shell, and then read the created files - as such</p>
  
  <pre><code>$descriptorspec = array
  (
      array("pipe", "r"),
      array("pipe", "w"),
      array("pipe", "w")
  );
  
  $pipes = array();
  $procedure = proc_open('cd "C:/Program Files/ffmpeg/bin" &amp;&amp; "ffmpeg.exe" -i "C:/wamp/www/sandbox/Wildlife.mp4" -deinterlace -qdiff 2 -ar 22050 "C:/wamp/www/sandbox/Wildlife.flv" &gt; C:/stdout.log 2&gt; C:/stderr.log', $descriptorspec, $pipes);
  
  proc_close($procedure);
  
  $output = file_get_contents("C:/stdout.log");
  $error = file_get_contents("C:/stderr.log");
  
  unlink("C:/stdout.log");
  unlink("C:/stderr.log");
  </code></pre>
  
  <p>As the stream is buffered, in the file we will get unbuffered output (something I was after as well). And we don't need to check if the file changes, because the result from shell is unbuffered and synchronous.</p>