PHP: Support proc_open
adamziel opened this issue · 2 comments
PHPUnit and wp-cli both use proc_open and will only work correctly in WordPress Playground if that function is supported.
Today proc_open does not work becuse internally it calls fork() which is not supported in Emscripten and doesn't seem possible to polyfill.
Therefore, the only way to support proc_open is to shim it using require('child_process').spawn() similarly to how we shim popen():
proc_open has the following signature in PHP:
proc_open(
array|string $command,
array $descriptor_spec,
array &$pipes,
?string $cwd = null,
?array $env_vars = null,
?array $options = null
): resource|falseHandling $pipes is the most challenging bit here. Emscripten documentation doesn't explain how to create pipes – the easiest way should be reading the code and looking up examples.
If we can find a way to open Emscripten pipes and pass the data from/to the child process, that's great – that would probably involve custom Emscripten streams or devices. Otherwise, we could fake pipes by opening three temporary files in Emscripten (for stdin, stdout, stderr) and creating $pipes using those file descriptor.
PHPUnit uses proc_open to support process isolation (which WordPress relies on):
if (!$this->shouldRunInSeparateProcess()) {
(new TestRunner)->run($this);
} else {
(new TestRunner)->runInSeparateProcess(
$this,
$this->runClassInSeparateProcess && !$this->runTestInSeparateProcess,
$this->preserveGlobalState,
);
}
}TestRunner::runInSeparateProcess:
$php = AbstractPhpProcess::factory();
$php->runTestJob($template->render(), $test);DefaultPhpProcess::runProcess():
$process = proc_open(
$this->getCommand($settings, $this->tempFile),
$pipeSpec,
$pipes,
null,
$env,
);