Skip to content

Commit a73ab0d

Browse files
authored
Merge pull request #29 from clue-labs/compat
[RFC] Improve compatibility with legacy versions
2 parents 6a092a7 + 29aab03 commit a73ab0d

4 files changed

Lines changed: 70 additions & 20 deletions

File tree

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
language: php
22

33
php:
4+
- 5.3
45
- 5.4
56
- 5.5
67
- 5.6

composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"keywords": ["process"],
55
"license": "MIT",
66
"require": {
7-
"php": ">=5.4.0",
8-
"evenement/evenement": "~2.0",
9-
"react/event-loop": "0.4.*",
7+
"php": ">=5.3.0",
8+
"evenement/evenement": "^2.0 || ^1.0",
9+
"react/event-loop": "^0.4 || ^0.3",
1010
"react/stream": "^0.5 || ^0.4.4"
1111
},
1212
"require-dev": {

src/Process.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,21 @@ public function start(LoopInterface $loop, $interval = 0.1)
103103

104104
$closeCount = 0;
105105

106-
$streamCloseHandler = function () use (&$closeCount, $loop, $interval) {
106+
$that = $this;
107+
$streamCloseHandler = function () use (&$closeCount, $loop, $interval, $that) {
107108
$closeCount++;
108109

109110
if ($closeCount < 2) {
110111
return;
111112
}
112113

113-
$loop->addPeriodicTimer($interval, function (TimerInterface $timer) {
114-
if (!$this->isRunning()) {
115-
$this->close();
114+
$loop->addPeriodicTimer($interval, function (TimerInterface $timer) use ($that) {
115+
if (!$that->isRunning()) {
116+
$that->close();
116117
$timer->cancel();
117-
$this->emit('exit', array($this->getExitCode(), $this->getTermSignal()));
118+
$that->emit('exit', array($that->getExitCode(), $that->getTermSignal()));
118119
}
119120
});
120-
121121
};
122122

123123
$this->stdin = new Stream($this->pipes[0], $loop);
@@ -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: 53 additions & 11 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;');
@@ -268,21 +308,22 @@ public function testTerminateWithStopAndContinueSignalsUsingEventLoop()
268308
$termSignal = func_get_arg(1);
269309
});
270310

271-
$loop->addTimer(0.001, function(Timer $timer) use ($process) {
311+
$that = $this;
312+
$loop->addTimer(0.001, function(Timer $timer) use ($process, $that) {
272313
$process->start($timer->getLoop());
273314
$process->terminate(SIGSTOP);
274315

275-
$this->assertSoon(function() use ($process) {
276-
$this->assertTrue($process->isStopped());
277-
$this->assertTrue($process->isRunning());
278-
$this->assertEquals(SIGSTOP, $process->getStopSignal());
316+
$that->assertSoon(function() use ($process, $that) {
317+
$that->assertTrue($process->isStopped());
318+
$that->assertTrue($process->isRunning());
319+
$that->assertEquals(SIGSTOP, $process->getStopSignal());
279320
});
280321

281322
$process->terminate(SIGCONT);
282323

283-
$this->assertSoon(function() use ($process) {
284-
$this->assertFalse($process->isStopped());
285-
$this->assertEquals(SIGSTOP, $process->getStopSignal());
324+
$that->assertSoon(function() use ($process, $that) {
325+
$that->assertFalse($process->isStopped());
326+
$that->assertEquals(SIGSTOP, $process->getStopSignal());
286327
});
287328
});
288329

@@ -308,12 +349,13 @@ public function testIssue18() {
308349
$stdOut = '';
309350
$stdErr = '';
310351

352+
$that = $this;
311353
$process->on(
312354
'exit',
313-
function ($exitCode) use (&$stdOut, &$stdErr, $testString) {
314-
$this->assertEquals(0, $exitCode, "Exit code is 0");
355+
function ($exitCode) use (&$stdOut, &$stdErr, $testString, $that) {
356+
$that->assertEquals(0, $exitCode, "Exit code is 0");
315357

316-
$this->assertEquals($testString, $stdOut);
358+
$that->assertEquals($testString, $stdOut);
317359
}
318360
);
319361

0 commit comments

Comments
 (0)