[Process] Fix stream_select priority when writing to stdin

This commit is contained in:
Nicolas Grekas 2016-03-29 18:06:47 +02:00
parent 2e6982ac67
commit f31e783fd4
4 changed files with 29 additions and 10 deletions

View File

@ -22,10 +22,9 @@ abstract class AbstractPipes implements PipesInterface
public $pipes = array();
/** @var string */
protected $inputBuffer = '';
private $inputBuffer = '';
/** @var resource|null */
protected $input;
private $input;
/** @var bool */
private $blocked = true;
@ -91,9 +90,8 @@ abstract class AbstractPipes implements PipesInterface
if (!isset($this->pipes[0])) {
return;
}
$e = array();
$r = null !== $this->input ? array($this->input) : $e;
$input = $this->input;
$r = $e = array();
$w = array($this->pipes[0]);
// let's have a look if something changed in streams
@ -110,7 +108,7 @@ abstract class AbstractPipes implements PipesInterface
}
}
foreach ($r as $input) {
if ($input) {
for (;;) {
$data = fread($input, self::CHUNK_SIZE);
if (!isset($data[0])) {
@ -124,7 +122,7 @@ abstract class AbstractPipes implements PipesInterface
return array($this->pipes[0]);
}
}
if (!isset($data[0]) && feof($input)) {
if (feof($input)) {
// no more data to read on input resource
// use an empty buffer in the next reads
$this->input = null;

View File

@ -158,7 +158,7 @@ class Process
$this->setEnv($env);
}
$this->input = $input;
$this->setInput($input);
$this->setTimeout($timeout);
$this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
$this->pty = false;

View File

@ -80,7 +80,7 @@ class ProcessUtils
* @param string $caller The name of method call that validates the input
* @param mixed $input The input to validate
*
* @return string The validated input
* @return mixed The validated input
*
* @throws InvalidArgumentException In case the input is not valid
*
@ -92,6 +92,9 @@ class ProcessUtils
if (is_resource($input)) {
return $input;
}
if (is_string($input)) {
return $input;
}
if (is_scalar($input)) {
return (string) $input;
}

View File

@ -209,6 +209,24 @@ class ProcessTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
}
public function testLiveStreamAsInput()
{
$stream = fopen('php://memory', 'r+');
fwrite($stream, 'hello');
rewind($stream);
$p = $this->getProcess(sprintf('%s -r %s', self::$phpBin, escapeshellarg('stream_copy_to_stream(STDIN, STDOUT);')));
$p->setInput($stream);
$p->start(function ($type, $data) use ($stream) {
if ('hello' === $data) {
fclose($stream);
}
});
$p->wait();
$this->assertSame('hello', $p->getOutput());
}
/**
* @expectedException \Symfony\Component\Process\Exception\LogicException
* @expectedExceptionMessage Input can not be set while the process is running.