Skip to content

Commit efd29d7

Browse files
committed
Support executing from CGI binary and simplify child command line (ps)
Try to look up php binary for child worker process when running from php-cgi binary. Additionally, chdir() to child worker source folder when spawning child to avoid lengthy command line (ps output).
1 parent 942c9cd commit efd29d7

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

src/Factory.php

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
class Factory
1313
{
1414
private $loop;
15-
15+
private $bin = PHP_BINARY;
1616
private $useSocket;
1717

1818
/**
@@ -32,6 +32,18 @@ public function __construct(LoopInterface $loop)
3232

3333
// use socket I/O for Windows only, use faster process pipes everywhere else
3434
$this->useSocket = DIRECTORY_SEPARATOR === '\\';
35+
36+
// if this is the php-cgi binary, check if we can execute the php binary instead
37+
$candidate = \str_replace('-cgi', '', $this->bin);
38+
if ($candidate !== $this->bin && \is_executable($candidate)) {
39+
$this->bin = $candidate; // @codeCoverageIgnore
40+
}
41+
42+
// if `php` is a symlink to the php binary, use the shorter `php` name
43+
// this is purely cosmetic feature for the process list
44+
if (\realpath($this->which('php')) === $this->bin) {
45+
$this->bin = 'php'; // @codeCoverageIgnore
46+
}
3547
}
3648

3749
/**
@@ -78,7 +90,7 @@ public function open($filename, $flags = null)
7890

7991
private function openProcessIo($filename, $flags = null)
8092
{
81-
$command = 'exec ' . \escapeshellarg(\PHP_BINARY) . ' ' . \escapeshellarg(__DIR__ . '/../res/sqlite-worker.php');
93+
$command = 'exec ' . \escapeshellarg($this->bin) . ' sqlite-worker.php';
8294

8395
// Try to get list of all open FDs (Linux/Mac and others)
8496
$fds = @\scandir('/dev/fd');
@@ -120,7 +132,7 @@ private function openProcessIo($filename, $flags = null)
120132
$command = 'exec bash -c ' . \escapeshellarg($command);
121133
}
122134

123-
$process = new Process($command, null, null, $pipes);
135+
$process = new Process($command, __DIR__ . '/../res', null, $pipes);
124136
$process->start($this->loop);
125137

126138
$db = new ProcessIoDatabase($process);
@@ -139,14 +151,14 @@ private function openProcessIo($filename, $flags = null)
139151

140152
private function openSocketIo($filename, $flags = null)
141153
{
142-
$command = \escapeshellarg(\PHP_BINARY) . ' ' . \escapeshellarg(__DIR__ . '/../res/sqlite-worker.php');
154+
$command = \escapeshellarg($this->bin) . ' sqlite-worker.php';
143155

144156
// launch process without default STDIO pipes
145157
$null = \DIRECTORY_SEPARATOR === '\\' ? 'nul' : '/dev/null';
146158
$pipes = array(
147159
array('file', $null, 'r'),
148160
array('file', $null, 'w'),
149-
STDERR // array('file', $null, 'w'),
161+
\defined('STDERR') ? \STDERR : \fopen('php://stderr', 'w')
150162
);
151163

152164
// start temporary socket on random address
@@ -161,7 +173,7 @@ private function openSocketIo($filename, $flags = null)
161173
stream_set_blocking($server, false);
162174
$command .= ' ' . stream_socket_get_name($server, false);
163175

164-
$process = new Process($command, null, null, $pipes);
176+
$process = new Process($command, __DIR__ . '/../res', null, $pipes);
165177
$process->start($this->loop);
166178

167179
$deferred = new Deferred(function () use ($process, $server) {
@@ -214,4 +226,19 @@ private function openSocketIo($filename, $flags = null)
214226

215227
return $deferred->promise();
216228
}
229+
230+
/**
231+
* @param string $bin
232+
* @return string|null
233+
* @codeCoverageIgnore
234+
*/
235+
private function which($bin)
236+
{
237+
foreach (\explode(\PATH_SEPARATOR, \getenv('PATH')) as $path) {
238+
if (\is_executable($path . \DIRECTORY_SEPARATOR . $bin)) {
239+
return $path . \DIRECTORY_SEPARATOR . $bin;
240+
}
241+
}
242+
return null;
243+
}
217244
}

0 commit comments

Comments
 (0)