Skip to content

Commit 29aab03

Browse files
committed
Work around SEGFAULT on legacy PHP < 5.4 due to unbuffered reads
1 parent b4f17f7 commit 29aab03

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

src/Process.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ public function start(LoopInterface $loop, $interval = 0.1)
126126
$this->stdout->on('close', $streamCloseHandler);
127127
$this->stderr = new Stream($this->pipes[2], $loop);
128128
$this->stderr->on('close', $streamCloseHandler);
129+
130+
// legacy PHP < 5.4 SEGFAULTs for unbuffered, non-blocking reads
131+
// work around by enabling read buffer again
132+
if (PHP_VERSION_ID < 50400) {
133+
stream_set_read_buffer($this->pipes[1], 1);
134+
stream_set_read_buffer($this->pipes[2], 1);
135+
}
129136
}
130137

131138
/**

tests/AbstractProcessTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,46 @@ public function testGetTermSignalWhenRunning($process)
6666
$this->assertNull($process->getTermSignal());
6767
}
6868

69+
public function testReceivesProcessStdoutFromEcho()
70+
{
71+
$cmd = 'echo test';
72+
73+
$loop = $this->createLoop();
74+
$process = new Process($cmd);
75+
$process->start($loop);
76+
77+
$buffer = '';
78+
$process->stdout->on('data', function ($data) use (&$buffer) {
79+
$buffer .= $data;
80+
});
81+
82+
$loop->run();
83+
84+
$this->assertEquals('test', rtrim($buffer));
85+
}
86+
87+
public function testReceivesProcessStdoutFromDd()
88+
{
89+
if (!file_exists('/dev/zero')) {
90+
$this->markTestSkipped('Unable to read from /dev/zero, Windows?');
91+
}
92+
93+
$cmd = 'dd if=/dev/zero bs=12345 count=1234';
94+
95+
$loop = $this->createLoop();
96+
$process = new Process($cmd);
97+
$process->start($loop);
98+
99+
$bytes = 0;
100+
$process->stdout->on('data', function ($data) use (&$bytes) {
101+
$bytes += strlen($data);
102+
});
103+
104+
$loop->run();
105+
106+
$this->assertEquals(12345 * 1234, $bytes);
107+
}
108+
69109
public function testProcessWithDefaultCwdAndEnv()
70110
{
71111
$cmd = $this->getPhpBinary() . ' -r ' . escapeshellarg('echo getcwd(), PHP_EOL, count($_SERVER), PHP_EOL;');

0 commit comments

Comments
 (0)